@zthun/helpful-fn 9.11.9 → 9.11.11

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/dist/index.cjs CHANGED
@@ -1,2151 +1,1920 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
-
5
- const uuid = require('uuid');
6
- const locale = require('date-fns/locale');
7
- const tz = require('@date-fns/tz');
8
- const dateFns = require('date-fns');
9
-
10
- /**
11
- * Represents a targeted point along a y axis.
12
- */ var ZVerticalAnchor = /*#__PURE__*/ function(ZVerticalAnchor) {
13
- /**
14
- * Top boundary.
15
- *
16
- * In vertical device space, this would equate to y = 0.
17
- */ ZVerticalAnchor["Top"] = "top";
18
- /**
19
- * Centerpoint between the top and bottom.
20
- */ ZVerticalAnchor["Middle"] = "middle";
21
- /**
22
- * Bottom boundary.
23
- *
24
- * In vertical device space, this would equate to y = Infinity.
25
- */ ZVerticalAnchor["Bottom"] = "bottom";
26
- return ZVerticalAnchor;
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let uuid = require("uuid");
3
+ let date_fns_locale = require("date-fns/locale");
4
+ let _date_fns_tz = require("@date-fns/tz");
5
+ let date_fns = require("date-fns");
6
+ //#region src/anchor/anchor.mts
7
+ /**
8
+ * Represents a targeted point along a y axis.
9
+ */ var ZVerticalAnchor = /* @__PURE__ */ function(ZVerticalAnchor) {
10
+ /**
11
+ * Top boundary.
12
+ *
13
+ * In vertical device space, this would equate to y = 0.
14
+ */ ZVerticalAnchor["Top"] = "top";
15
+ /**
16
+ * Centerpoint between the top and bottom.
17
+ */ ZVerticalAnchor["Middle"] = "middle";
18
+ /**
19
+ * Bottom boundary.
20
+ *
21
+ * In vertical device space, this would equate to y = Infinity.
22
+ */ ZVerticalAnchor["Bottom"] = "bottom";
23
+ return ZVerticalAnchor;
27
24
  }({});
28
25
  /**
29
- * Represents a targeted point along an x axis.
30
- */ var ZHorizontalAnchor = /*#__PURE__*/ function(ZHorizontalAnchor) {
31
- /**
32
- * Left boundary.
33
- *
34
- * In horizontal device space, this would equate to x = 0.
35
- */ ZHorizontalAnchor["Left"] = "left";
36
- /**
37
- * Centerpoint between the left and right boundary.
38
- */ ZHorizontalAnchor["Center"] = "center";
39
- /**
40
- * Right boundary.
41
- *
42
- * In horizontal device space, this would equate to x = Infinity.
43
- */ ZHorizontalAnchor["Right"] = "right";
44
- return ZHorizontalAnchor;
26
+ * Represents a targeted point along an x axis.
27
+ */ var ZHorizontalAnchor = /* @__PURE__ */ function(ZHorizontalAnchor) {
28
+ /**
29
+ * Left boundary.
30
+ *
31
+ * In horizontal device space, this would equate to x = 0.
32
+ */ ZHorizontalAnchor["Left"] = "left";
33
+ /**
34
+ * Centerpoint between the left and right boundary.
35
+ */ ZHorizontalAnchor["Center"] = "center";
36
+ /**
37
+ * Right boundary.
38
+ *
39
+ * In horizontal device space, this would equate to x = Infinity.
40
+ */ ZHorizontalAnchor["Right"] = "right";
41
+ return ZHorizontalAnchor;
45
42
  }({});
46
-
47
- function _define_property$7(obj, key, value) {
48
- if (key in obj) {
49
- Object.defineProperty(obj, key, {
50
- value: value,
51
- enumerable: true,
52
- configurable: true,
53
- writable: true
54
- });
55
- } else {
56
- obj[key] = value;
57
- }
58
- return obj;
43
+ //#endregion
44
+ //#region src/assert/assert.mts
45
+ /**
46
+ * Represents an object that can be used to build a list of assertions.
47
+ *
48
+ * @example
49
+ *
50
+ * ```ts
51
+ * import { ZAssert, createError } from '@zthun/helpful-fn';
52
+ *
53
+ * const user = readUser();
54
+ *
55
+ * ZAssert
56
+ * .claim(user.name != null, 'User name is required')
57
+ * .claim(user.email != null, 'User email is required')
58
+ * .assert((m) => createError(m));
59
+ * ```
60
+ */ var ZAssert = class ZAssert {
61
+ /**
62
+ * Initializes a new instance of a ZAssert with one claim.
63
+ *
64
+ * @param claim -
65
+ * The claim to make.
66
+ * @param msg -
67
+ * The message to throw if the claim is false.
68
+ *
69
+ * @returns
70
+ * A new ZAssert object with an initial claim.
71
+ */ static claim(claim, msg) {
72
+ return new ZAssert().claim(claim, msg);
73
+ }
74
+ _messages = [];
75
+ /**
76
+ * Initializes a new instance of this object.
77
+ */ constructor() {}
78
+ /**
79
+ * Adds a claim.
80
+ *
81
+ * @param claim -
82
+ * The claim predicate.
83
+ * @param msg -
84
+ * The message to add if the claim fails.
85
+ *
86
+ * @returns This object.
87
+ */ claim(claim, msg) {
88
+ if (!claim) this._messages.push(msg);
89
+ return this;
90
+ }
91
+ /**
92
+ * Runs the assertion.
93
+ *
94
+ * @param fail -
95
+ * The factory that is responsible for returning the specified error to throw.
96
+ */ assert(fail) {
97
+ if (this._messages.length === 1) throw fail(this._messages[0]);
98
+ if (this._messages.length) throw fail(this._messages);
99
+ }
100
+ };
101
+ //#endregion
102
+ //#region src/enum/is-enum.mts
103
+ /**
104
+ * Gets whether the candidate can represent an enumeration object of type TEnum.
105
+ *
106
+ * This is mostly helpful for type guarding value options in a type.
107
+ *
108
+ * @param enumeration -
109
+ * The enumeration object that contains the values.
110
+ * @param candidate -
111
+ * The candidate to check.
112
+ *
113
+ * @returns
114
+ * True if candidate can represents one of the white listed
115
+ * object values in enumeration.
116
+ */ function isEnum(enumeration, candidate) {
117
+ return candidate != null && (typeof candidate === "string" || typeof candidate === "number") && Object.values(enumeration).includes(candidate);
59
118
  }
60
- /**
61
- * Represents an object that can be used to build a list of assertions.
62
- *
63
- * @example
64
- *
65
- * ```ts
66
- * import { ZAssert, createError } from '@zthun/helpful-fn';
67
- *
68
- * const user = readUser();
69
- *
70
- * ZAssert
71
- * .claim(user.name != null, 'User name is required')
72
- * .claim(user.email != null, 'User email is required')
73
- * .assert((m) => createError(m));
74
- * ```
75
- */ class ZAssert {
76
- /**
77
- * Initializes a new instance of a ZAssert with one claim.
78
- *
79
- * @param claim -
80
- * The claim to make.
81
- * @param msg -
82
- * The message to throw if the claim is false.
83
- *
84
- * @returns
85
- * A new ZAssert object with an initial claim.
86
- */ static claim(claim, msg) {
87
- return new ZAssert().claim(claim, msg);
88
- }
89
- /**
90
- * Adds a claim.
91
- *
92
- * @param claim -
93
- * The claim predicate.
94
- * @param msg -
95
- * The message to add if the claim fails.
96
- *
97
- * @returns This object.
98
- */ claim(claim, msg) {
99
- if (!claim) {
100
- this._messages.push(msg);
101
- }
102
- return this;
103
- }
104
- /**
105
- * Runs the assertion.
106
- *
107
- * @param fail -
108
- * The factory that is responsible for returning the specified error to throw.
109
- */ assert(fail) {
110
- if (this._messages.length === 1) {
111
- throw fail(this._messages[0]);
112
- }
113
- if (this._messages.length) {
114
- throw fail(this._messages);
115
- }
116
- }
117
- /**
118
- * Initializes a new instance of this object.
119
- */ constructor(){
120
- _define_property$7(this, "_messages", []);
121
- }
119
+ //#endregion
120
+ //#region src/cast/cast-enum.mts
121
+ /**
122
+ * Attempts to cast the candidate to an enumeration value.
123
+ *
124
+ * @param enumeration -
125
+ * The enumeration type.
126
+ * @param candidate -
127
+ * The candidate to cast to the enum type.
128
+ * @param fallback -
129
+ * The fallback to use in the case that candidate
130
+ * cannot represent the enumeration type.
131
+ *
132
+ * @returns
133
+ * The candidate if candidate represents the enumeration type,
134
+ * or fallback in the case that it does not.
135
+ */ function castEnum(enumeration, candidate, fallback) {
136
+ return isEnum(enumeration, candidate) ? candidate : fallback;
122
137
  }
123
-
124
- /**
125
- * Gets whether the candidate can represent an enumeration object of type TEnum.
126
- *
127
- * This is mostly helpful for type guarding value options in a type.
128
- *
129
- * @param enumeration -
130
- * The enumeration object that contains the values.
131
- * @param candidate -
132
- * The candidate to check.
133
- *
134
- * @returns
135
- * True if candidate can represents one of the white listed
136
- * object values in enumeration.
137
- */ function isEnum(enumeration, candidate) {
138
- return candidate != null && (typeof candidate === "string" || typeof candidate === "number") && Object.values(enumeration).includes(candidate);
138
+ //#endregion
139
+ //#region src/cast/cast-extension.mts
140
+ /**
141
+ * Puts a . in front of name if one is not already there.
142
+ *
143
+ * If there are multiple dots in front of name, then
144
+ * all dots but one is removed.
145
+ *
146
+ * @example
147
+ *
148
+ * ```ts
149
+ * // Outputs .zip
150
+ * castExtension('zip');
151
+ *
152
+ * // Outputs .zip
153
+ * castExtension('.zip');
154
+ *
155
+ * // Outputs .zip
156
+ * castExtension('...zip');
157
+ * ```
158
+ *
159
+ * @param candidate -
160
+ * The candidate extension
161
+ *
162
+ * @returns
163
+ * The candidate prepended by a single dot.
164
+ * If candidate is undefined, null, the empty
165
+ * string, white space, or nothing but dots,
166
+ * then the empty string is returned.
167
+ */ function castExtension(candidate) {
168
+ if (candidate == null) return "";
169
+ const trimmed = candidate.trim();
170
+ if (!trimmed) return "";
171
+ const normalized = trimmed.replace(/^\.+/, "");
172
+ if (!normalized) return "";
173
+ return `.${normalized}`;
139
174
  }
140
-
141
- /**
142
- * Attempts to cast the candidate to an enumeration value.
143
- *
144
- * @param enumeration -
145
- * The enumeration type.
146
- * @param candidate -
147
- * The candidate to cast to the enum type.
148
- * @param fallback -
149
- * The fallback to use in the case that candidate
150
- * cannot represent the enumeration type.
151
- *
152
- * @returns
153
- * The candidate if candidate represents the enumeration type,
154
- * or fallback in the case that it does not.
155
- */ function castEnum(enumeration, candidate, fallback) {
156
- return isEnum(enumeration, candidate) ? candidate : fallback;
175
+ //#endregion
176
+ //#region src/cast/cast-number.mts
177
+ /**
178
+ * Attempts to cast candidate to a number.
179
+ *
180
+ * This method assumes you want an actual number and
181
+ * not NaN. In the case that candidate results in
182
+ * NaN, then the fallback condition applies.
183
+ *
184
+ * @param candidate -
185
+ * The candidate to cast.
186
+ *
187
+ * @returns
188
+ * The casted number or undefined in the cast
189
+ * that casting candidate would result in NaN.
190
+ */ /**
191
+ * Attempts to cast candidate to a number.
192
+ *
193
+ * This method assumes you want an actual number and
194
+ * not NaN. In the case that candidate results in
195
+ * NaN, then the fallback condition applies.
196
+ *
197
+ * @param candidate -
198
+ * The candidate to cast.
199
+ * @param fallback -
200
+ * The fallback value in the case that the result
201
+ * of casting candidate would result in NaN
202
+ *
203
+ * @returns
204
+ * The casted number or fallback in the cast
205
+ * that casting candidate would result in NaN.
206
+ */ function castNumber(candidate, fallback) {
207
+ try {
208
+ const casted = Number(candidate);
209
+ return Number.isNaN(casted) ? fallback : casted;
210
+ } catch {
211
+ return fallback;
212
+ }
157
213
  }
158
-
159
- /**
160
- * Puts a . in front of name if one is not already there.
161
- *
162
- * If there are multiple dots in front of name, then
163
- * all dots but one is removed.
164
- *
165
- * @example
166
- *
167
- * ```ts
168
- * // Outputs .zip
169
- * castExtension('zip');
170
- *
171
- * // Outputs .zip
172
- * castExtension('.zip');
173
- *
174
- * // Outputs .zip
175
- * castExtension('...zip');
176
- * ```
177
- *
178
- * @param candidate -
179
- * The candidate extension
180
- *
181
- * @returns
182
- * The candidate prepended by a single dot.
183
- * If candidate is undefined, null, the empty
184
- * string, white space, or nothing but dots,
185
- * then the empty string is returned.
186
- */ function castExtension(candidate) {
187
- if (candidate == null) {
188
- return "";
189
- }
190
- const trimmed = candidate.trim();
191
- if (!trimmed) {
192
- return "";
193
- }
194
- const normalized = trimmed.replace(/^\.+/, "");
195
- if (!normalized) {
196
- return "";
197
- }
198
- return `.${normalized}`;
214
+ //#endregion
215
+ //#region src/count-buckets/count-buckets.mts
216
+ /**
217
+ * Calculates the total number of buckets you need to
218
+ * store a number of items where each bucket can hold a
219
+ * maximum weight of items.
220
+ *
221
+ * You can use this function to calculate groupings of
222
+ * items based on total counts and sizes. A good example
223
+ * usage would be to calculate the total number of pages
224
+ * on a paginated list of items given a page size and item
225
+ * count.
226
+ *
227
+ * @param weight -
228
+ * The maximum weight a bucket can store. If this value receives
229
+ * Infinity, then it will result in 1 or min buckets being returned,
230
+ * whichever is larger. If this receives NaN, then this method will
231
+ * result in NaN. Finally, if this receives a negative value, then
232
+ * the result will be max.
233
+ * @param items -
234
+ * The total number of items you need to store where each item
235
+ * counts as 1 towards the weight. If the total number of items
236
+ * is Infinity, then this method will result in max buckets.
237
+ * If this receives NaN, then this method will result in NaN. Finally,
238
+ * if you pass 0, or a negative number of items, then result will be min.
239
+ * @param min -
240
+ * The bounded minimum value. If the total number of buckets
241
+ * evaluates to less than this value, then this value is returned.
242
+ * The default is 0.
243
+ * @param max -
244
+ * The bounded maximum value. If the total number of buckets
245
+ * evaluates to more than this value, then this value is returned.
246
+ * The default is Infinity.
247
+ *
248
+ * @returns
249
+ * The number of buckets you need to store the total number
250
+ * of items given that a single bucket can hold a max weight of items.
251
+ * If either weight or items is NaN, then NaN will be returned regardless
252
+ * of the opposite value. Passing a negative number is the same as
253
+ * passing 0.
254
+ *
255
+ * @example
256
+ *
257
+ * ```ts
258
+ * // The following will return 5 for numberOfPages since you need 5 buckets
259
+ * // to store 101 number of items where each bucket can hold a max of 25
260
+ * // items. The 5th page would be a page of 1 item, since 1 is the remainder.
261
+ * const numberOfPages = countBuckets(25, 101);
262
+ *
263
+ * // In this case, the numberOfPages would be 1 here since our minimum buckets
264
+ * // is 1. By default, this would be 0.
265
+ * const numberOfPages = countBuckets(10, 0, 1);
266
+ *
267
+ * // In this case, we have more items that can be held in the number of buckets
268
+ * // available, so only 4 is returned instead of the 5.
269
+ * const numberOfPages = countBuckets(25, 101, undefined, 4);
270
+ * ```
271
+ */ function countBuckets(weight, items, min = 0, max = Infinity) {
272
+ weight = Math.max(0, weight);
273
+ items = Math.max(0, items);
274
+ if (Number.isNaN(weight) || Number.isNaN(items)) return NaN;
275
+ if (items === 0) return min;
276
+ const boxes = weight === Infinity ? 1 : Math.ceil(items / weight);
277
+ return Math.min(max, Math.max(min, boxes));
199
278
  }
200
-
201
- /**
202
- * Attempts to cast candidate to a number.
203
- *
204
- * This method assumes you want an actual number and
205
- * not NaN. In the case that candidate results in
206
- * NaN, then the fallback condition applies.
207
- *
208
- * @param candidate -
209
- * The candidate to cast.
210
- *
211
- * @returns
212
- * The casted number or undefined in the cast
213
- * that casting candidate would result in NaN.
214
- */ /**
215
- * Attempts to cast candidate to a number.
216
- *
217
- * This method assumes you want an actual number and
218
- * not NaN. In the case that candidate results in
219
- * NaN, then the fallback condition applies.
220
- *
221
- * @param candidate -
222
- * The candidate to cast.
223
- * @param fallback -
224
- * The fallback value in the case that the result
225
- * of casting candidate would result in NaN
226
- *
227
- * @returns
228
- * The casted number or fallback in the cast
229
- * that casting candidate would result in NaN.
230
- */ function castNumber(candidate, fallback) {
231
- try {
232
- const casted = Number(candidate);
233
- return Number.isNaN(casted) ? fallback : casted;
234
- } catch {
235
- return fallback;
236
- }
237
- }
238
-
239
- /**
240
- * Calculates the total number of buckets you need to
241
- * store a number of items where each bucket can hold a
242
- * maximum weight of items.
243
- *
244
- * You can use this function to calculate groupings of
245
- * items based on total counts and sizes. A good example
246
- * usage would be to calculate the total number of pages
247
- * on a paginated list of items given a page size and item
248
- * count.
249
- *
250
- * @param weight -
251
- * The maximum weight a bucket can store. If this value receives
252
- * Infinity, then it will result in 1 or min buckets being returned,
253
- * whichever is larger. If this receives NaN, then this method will
254
- * result in NaN. Finally, if this receives a negative value, then
255
- * the result will be max.
256
- * @param items -
257
- * The total number of items you need to store where each item
258
- * counts as 1 towards the weight. If the total number of items
259
- * is Infinity, then this method will result in max buckets.
260
- * If this receives NaN, then this method will result in NaN. Finally,
261
- * if you pass 0, or a negative number of items, then result will be min.
262
- * @param min -
263
- * The bounded minimum value. If the total number of buckets
264
- * evaluates to less than this value, then this value is returned.
265
- * The default is 0.
266
- * @param max -
267
- * The bounded maximum value. If the total number of buckets
268
- * evaluates to more than this value, then this value is returned.
269
- * The default is Infinity.
270
- *
271
- * @returns
272
- * The number of buckets you need to store the total number
273
- * of items given that a single bucket can hold a max weight of items.
274
- * If either weight or items is NaN, then NaN will be returned regardless
275
- * of the opposite value. Passing a negative number is the same as
276
- * passing 0.
277
- *
278
- * @example
279
- *
280
- * ```ts
281
- * // The following will return 5 for numberOfPages since you need 5 buckets
282
- * // to store 101 number of items where each bucket can hold a max of 25
283
- * // items. The 5th page would be a page of 1 item, since 1 is the remainder.
284
- * const numberOfPages = countBuckets(25, 101);
285
- *
286
- * // In this case, the numberOfPages would be 1 here since our minimum buckets
287
- * // is 1. By default, this would be 0.
288
- * const numberOfPages = countBuckets(10, 0, 1);
289
- *
290
- * // In this case, we have more items that can be held in the number of buckets
291
- * // available, so only 4 is returned instead of the 5.
292
- * const numberOfPages = countBuckets(25, 101, undefined, 4);
293
- * ```
294
- */ function countBuckets(weight, items, min = 0, max = Infinity) {
295
- weight = Math.max(0, weight);
296
- items = Math.max(0, items);
297
- if (Number.isNaN(weight) || Number.isNaN(items)) {
298
- return NaN;
299
- }
300
- if (items === 0) {
301
- return min;
302
- }
303
- const boxes = weight === Infinity ? 1 : Math.ceil(items / weight);
304
- return Math.min(max, Math.max(min, boxes));
305
- }
306
-
307
- /**
308
- * A helper method to construct a JavaScript error object given a list of acceptable schema keys.
309
- *
310
- * @param problem -
311
- * A generic representation of the problem that occurred. This can be an Error object,
312
- * another object representing some kind of error, or some message representing the error.
313
- * If this is null or undefined, then a generic error is returned.
314
- * @param schema -
315
- * The list of acceptable object keys to look into problem. These will be recursively
316
- * evaluated to strip out the real error message. Note that this is in order of
317
- * priority. If schema[0] and schema[1] are both keys on problem, then schema[0] takes
318
- * a higher precedence than schema[1]. By default, the schema will look for properties
319
- * named, message, error, exception, and data, in that order.
320
- *
321
- * @returns
322
- * An error object that is the best evaluation of what the problem actually is.
323
- *
324
- * @example
325
- *
326
- * ```ts
327
- * // All of these result an Error with the message, 'Something went wrong'
328
- * const errorWithStringProblem = createError('Something went wrong');
329
- * const errorWithObjectProblemInSchema = createError({ error: 'Something went wrong'});
330
- * const errorWithCustomSchema = createError({ issue: 'Something went wrong'}, ['issue']);
331
- * const errorRecursive = createError({ error: { message: 'Something went wrong' }});
332
- *
333
- * // This would result in '[Object object]' as there is no way to figure out how to deconstruct this problem.
334
- * const errorCannotBeFound = createError({ wut: 'Something went wrong' });
335
- * ```
336
- */ function createError(problem, schema = [
337
- "message",
338
- "error",
339
- "exception",
340
- "data"
279
+ //#endregion
280
+ //#region src/create-error/create-error.mts
281
+ /**
282
+ * A helper method to construct a JavaScript error object given a list of acceptable schema keys.
283
+ *
284
+ * @param problem -
285
+ * A generic representation of the problem that occurred. This can be an Error object,
286
+ * another object representing some kind of error, or some message representing the error.
287
+ * If this is null or undefined, then a generic error is returned.
288
+ * @param schema -
289
+ * The list of acceptable object keys to look into problem. These will be recursively
290
+ * evaluated to strip out the real error message. Note that this is in order of
291
+ * priority. If schema[0] and schema[1] are both keys on problem, then schema[0] takes
292
+ * a higher precedence than schema[1]. By default, the schema will look for properties
293
+ * named, message, error, exception, and data, in that order.
294
+ *
295
+ * @returns
296
+ * An error object that is the best evaluation of what the problem actually is.
297
+ *
298
+ * @example
299
+ *
300
+ * ```ts
301
+ * // All of these result an Error with the message, 'Something went wrong'
302
+ * const errorWithStringProblem = createError('Something went wrong');
303
+ * const errorWithObjectProblemInSchema = createError({ error: 'Something went wrong'});
304
+ * const errorWithCustomSchema = createError({ issue: 'Something went wrong'}, ['issue']);
305
+ * const errorRecursive = createError({ error: { message: 'Something went wrong' }});
306
+ *
307
+ * // This would result in '[Object object]' as there is no way to figure out how to deconstruct this problem.
308
+ * const errorCannotBeFound = createError({ wut: 'Something went wrong' });
309
+ * ```
310
+ */ function createError(problem, schema = [
311
+ "message",
312
+ "error",
313
+ "exception",
314
+ "data"
341
315
  ]) {
342
- if (problem instanceof Error) {
343
- return problem;
344
- }
345
- if (problem == null) {
346
- return new Error();
347
- }
348
- for(let i = 0; i < schema.length; ++i){
349
- const key = schema[i];
350
- if (Object.prototype.hasOwnProperty.call(problem, key)) {
351
- return createError(problem[key]);
352
- }
353
- }
354
- return new Error(String(problem));
316
+ if (problem instanceof Error) return problem;
317
+ if (problem == null) return /* @__PURE__ */ new Error();
318
+ for (let i = 0; i < schema.length; ++i) {
319
+ const key = schema[i];
320
+ if (Object.prototype.hasOwnProperty.call(problem, key)) return createError(problem[key]);
321
+ }
322
+ return new Error(String(problem));
355
323
  }
356
-
357
- /**
358
- * Creates a globally unique identifier.
359
- *
360
- * The identifier holds to v4 of the UUID specification. A summary
361
- * of the specification can be found at
362
- * {@link https://commons.apache.org/sandbox/commons-id/uuid.html | Apache Commons UUID Documentation}.
363
- *
364
- * The official documentation of the UUID specification is under
365
- * {@link https://www.rfc-editor.org/info/rfc4122 | RFC 4122}
366
- *
367
- * @returns
368
- * A new generated globally unique identifier based on random bytes.
369
- *
370
- * @example
371
- *
372
- * ```ts
373
- * // Will get a value similar to 53e33fb6-d05a-4fa9-8dc0-b78e4feaa702
374
- * const guidA = createGuid();
375
- * // Will most likely not ever be equal to guidA
376
- * const guidB = createGuid();
377
- * ```
378
- */ const createGuid = uuid.v4;
379
-
380
- /**
381
- * Supported locales from date-fns.
382
- *
383
- * This should not be exported. This is an internal helper.
384
- */ const LocaleLookup = {
385
- [locale.enAU.code]: locale.enAU,
386
- [locale.enCA.code]: locale.enCA,
387
- [locale.enGB.code]: locale.enGB,
388
- [locale.enIE.code]: locale.enIE,
389
- [locale.enIN.code]: locale.enIN,
390
- [locale.enNZ.code]: locale.enNZ,
391
- [locale.enUS.code]: locale.enUS,
392
- [locale.enZA.code]: locale.enZA,
393
- [locale.ja.code]: locale.ja
324
+ //#endregion
325
+ //#region src/create-guid/create-guid.mts
326
+ /**
327
+ * Creates a globally unique identifier.
328
+ *
329
+ * The identifier holds to v4 of the UUID specification. A summary
330
+ * of the specification can be found at
331
+ * {@link https://commons.apache.org/sandbox/commons-id/uuid.html | Apache Commons UUID Documentation}.
332
+ *
333
+ * The official documentation of the UUID specification is under
334
+ * {@link https://www.rfc-editor.org/info/rfc4122 | RFC 4122}
335
+ *
336
+ * @returns
337
+ * A new generated globally unique identifier based on random bytes.
338
+ *
339
+ * @example
340
+ *
341
+ * ```ts
342
+ * // Will get a value similar to 53e33fb6-d05a-4fa9-8dc0-b78e4feaa702
343
+ * const guidA = createGuid();
344
+ * // Will most likely not ever be equal to guidA
345
+ * const guidB = createGuid();
346
+ * ```
347
+ */ var createGuid = uuid.v4;
348
+ //#endregion
349
+ //#region src/culture/locale-lookup.mts
350
+ /**
351
+ * Supported locales from date-fns.
352
+ *
353
+ * This should not be exported. This is an internal helper.
354
+ */ var LocaleLookup = {
355
+ [date_fns_locale.enAU.code]: date_fns_locale.enAU,
356
+ [date_fns_locale.enCA.code]: date_fns_locale.enCA,
357
+ [date_fns_locale.enGB.code]: date_fns_locale.enGB,
358
+ [date_fns_locale.enIE.code]: date_fns_locale.enIE,
359
+ [date_fns_locale.enIN.code]: date_fns_locale.enIN,
360
+ [date_fns_locale.enNZ.code]: date_fns_locale.enNZ,
361
+ [date_fns_locale.enUS.code]: date_fns_locale.enUS,
362
+ [date_fns_locale.enZA.code]: date_fns_locale.enZA,
363
+ [date_fns_locale.ja.code]: date_fns_locale.ja
394
364
  };
395
-
396
- /**
397
- * Returns the users current culture (locale).
398
- *
399
- * @returns
400
- * The current locale.
401
- */ function culture() {
402
- const locale = Intl.DateTimeFormat().resolvedOptions().locale;
403
- return locale;
365
+ //#endregion
366
+ //#region src/culture/culture.mts
367
+ /**
368
+ * Returns the users current culture (locale).
369
+ *
370
+ * @returns
371
+ * The current locale.
372
+ */ function culture() {
373
+ return Intl.DateTimeFormat().resolvedOptions().locale;
404
374
  }
405
375
  /**
406
- * Returns all supported cultures.
407
- *
408
- * @returns
409
- * A list of currently supported culture codes.
410
- */ function cultures() {
411
- return Object.keys(LocaleLookup);
376
+ * Returns all supported cultures.
377
+ *
378
+ * @returns
379
+ * A list of currently supported culture codes.
380
+ */ function cultures() {
381
+ return Object.keys(LocaleLookup);
412
382
  }
413
-
414
- /**
415
- * Returns the user's current timezone.
416
- *
417
- * @returns
418
- * The users current timezone.
419
- */ function userTimeZone() {
420
- return Intl.DateTimeFormat().resolvedOptions().timeZone;
383
+ //#endregion
384
+ //#region src/date/timezone.mts
385
+ /**
386
+ * Returns the user's current timezone.
387
+ *
388
+ * @returns
389
+ * The users current timezone.
390
+ */ function userTimeZone() {
391
+ return Intl.DateTimeFormat().resolvedOptions().timeZone;
421
392
  }
422
393
  /**
423
- * Returns the list of all supported timezones.
424
- *
425
- * @returns
426
- * A list of all timezone values.
427
- */ function timeZones() {
428
- return Intl.supportedValuesOf("timeZone");
394
+ * Returns the list of all supported timezones.
395
+ *
396
+ * @returns
397
+ * A list of all timezone values.
398
+ */ function timeZones() {
399
+ return Intl.supportedValuesOf("timeZone");
429
400
  }
430
-
431
- /**
432
- * Parses a string value back to a date format.
433
- *
434
- *
435
- * @param value -
436
- * The value to parse
437
- * @param options -
438
- * The options to parse with. The most important option here is format.
439
- * If the format is not specified, then the standard zoned ISO 8601
440
- * format is used. The timezone is also used in the case the date
441
- * does not supply it for string values. If the timezone is not specified
442
- * then the users timezone is assumed. Finally, the cultural local will
443
- * default to the users current culture if not specified.
444
- *
445
- * @returns
446
- * The date object parsed from the value. Returns null
447
- * if the value parsed with the given options results in an
448
- * invalid date.
449
- */ function parseDateTime(value, options = {}) {
450
- const { fallback = null } = options;
451
- if (value == null) {
452
- return fallback;
453
- }
454
- if (typeof value === "number") {
455
- const candidate = new Date(value);
456
- return Number.isNaN(candidate.getTime()) ? fallback : candidate;
457
- }
458
- if (value instanceof Date) {
459
- return Number.isNaN(value.getTime()) ? fallback : value;
460
- }
461
- const { format = ZDateFormats.Iso, culture: culture$1 = culture(), timeZone = userTimeZone() } = options;
462
- const locale = LocaleLookup[culture$1];
463
- const reference = new tz.TZDate(dateFns.startOfToday()).withTimeZone(timeZone);
464
- const result = dateFns.parse(value, format, reference, {
465
- locale
466
- });
467
- return Number.isNaN(result.getTime()) ? fallback : result;
401
+ //#endregion
402
+ //#region src/date/parse-date.mts
403
+ /**
404
+ * Parses a string value back to a date format.
405
+ *
406
+ *
407
+ * @param value -
408
+ * The value to parse
409
+ * @param options -
410
+ * The options to parse with. The most important option here is format.
411
+ * If the format is not specified, then the standard zoned ISO 8601
412
+ * format is used. The timezone is also used in the case the date
413
+ * does not supply it for string values. If the timezone is not specified
414
+ * then the users timezone is assumed. Finally, the cultural local will
415
+ * default to the users current culture if not specified.
416
+ *
417
+ * @returns
418
+ * The date object parsed from the value. Returns null
419
+ * if the value parsed with the given options results in an
420
+ * invalid date.
421
+ */ function parseDateTime(value, options = {}) {
422
+ const { fallback = null } = options;
423
+ if (value == null) return fallback;
424
+ if (typeof value === "number") {
425
+ const candidate = new Date(value);
426
+ return Number.isNaN(candidate.getTime()) ? fallback : candidate;
427
+ }
428
+ if (value instanceof Date) return Number.isNaN(value.getTime()) ? fallback : value;
429
+ const { format = ZDateFormats.Iso, culture: culture$2 = culture(), timeZone = userTimeZone() } = options;
430
+ const locale = LocaleLookup[culture$2];
431
+ const result = (0, date_fns.parse)(value, format, new _date_fns_tz.TZDate((0, date_fns.startOfToday)()).withTimeZone(timeZone), { locale });
432
+ return Number.isNaN(result.getTime()) ? fallback : result;
468
433
  }
469
-
470
- /**
471
- * Similar to {@link parseDateTime} but tries multiple supported formats.
472
- *
473
- * @param value -
474
- * The value to parse that may result in a date.
475
- * @param options -
476
- * The options for guessing the date. These will be forwarded to parse
477
- * for processing.
478
- */ function guessDateTime(value, options = {}) {
479
- const { fallback = null } = options;
480
- if (value == null) {
481
- return fallback;
482
- }
483
- const { supportedFormats = Object.values(ZDateFormats) } = options;
484
- for (const fmt of supportedFormats){
485
- const inner = {
486
- ...options
487
- };
488
- inner.format = fmt;
489
- const result = parseDateTime(value, inner);
490
- if (result != null) {
491
- return result;
492
- }
493
- }
494
- return fallback;
434
+ //#endregion
435
+ //#region src/date/guess-date.mts
436
+ /**
437
+ * Similar to {@link parseDateTime} but tries multiple supported formats.
438
+ *
439
+ * @param value -
440
+ * The value to parse that may result in a date.
441
+ * @param options -
442
+ * The options for guessing the date. These will be forwarded to parse
443
+ * for processing.
444
+ */ function guessDateTime(value, options = {}) {
445
+ const { fallback = null } = options;
446
+ if (value == null) return fallback;
447
+ const { supportedFormats = Object.values(ZDateFormats) } = options;
448
+ for (const fmt of supportedFormats) {
449
+ const inner = { ...options };
450
+ inner.format = fmt;
451
+ const result = parseDateTime(value, inner);
452
+ if (result != null) return result;
453
+ }
454
+ return fallback;
495
455
  }
496
-
497
- /**
498
- * Basic date formats that are common for storage and usage.
499
- */ var ZDateFormats = /*#__PURE__*/ function(ZDateFormats) {
500
- /**
501
- * Standard {@link https://en.wikipedia.org/wiki/ISO_8601 | ISO-8601} format with date only.
502
- *
503
- * Using this should imply midnight user timezone.
504
- */ ZDateFormats["IsoDateOnly"] = "yyyy-MM-dd";
505
- /**
506
- * Standard {@link https://en.wikipedia.org/wiki/ISO_8601 | ISO-8601} format with time only.
507
- */ ZDateFormats["IsoTimeOnly"] = "HH:mm:ss.SSS";
508
- /**
509
- * Standard {@link https://en.wikipedia.org/wiki/ISO_8601 | ISO-8601} format without timezone specifier.
510
- */ ZDateFormats["IsoNoTimeZone"] = "yyyy-MM-dd'T'HH:mm:ss.SSS";
511
- /**
512
- * Standard {@link https://en.wikipedia.org/wiki/ISO_8601 | ISO-8601} format.
513
- */ ZDateFormats["Iso"] = "yyyy-MM-dd'T'HH:mm:ss.SSSXX";
514
- /**
515
- * Users local date (locale specific).
516
- */ ZDateFormats["LocalDate"] = "P";
517
- /**
518
- * User local time (locale specific).
519
- */ ZDateFormats["LocalTime"] = "p";
520
- /**
521
- * Date and time formatted with user specific locale.
522
- */ ZDateFormats["LocalDateTime"] = "Pp";
523
- return ZDateFormats;
456
+ //#endregion
457
+ //#region src/date/format-date.mts
458
+ /**
459
+ * Basic date formats that are common for storage and usage.
460
+ */ var ZDateFormats = /* @__PURE__ */ function(ZDateFormats) {
461
+ /**
462
+ * Standard {@link https://en.wikipedia.org/wiki/ISO_8601 | ISO-8601} format with date only.
463
+ *
464
+ * Using this should imply midnight user timezone.
465
+ */ ZDateFormats["IsoDateOnly"] = "yyyy-MM-dd";
466
+ /**
467
+ * Standard {@link https://en.wikipedia.org/wiki/ISO_8601 | ISO-8601} format with time only.
468
+ */ ZDateFormats["IsoTimeOnly"] = "HH:mm:ss.SSS";
469
+ /**
470
+ * Standard {@link https://en.wikipedia.org/wiki/ISO_8601 | ISO-8601} format without timezone specifier.
471
+ */ ZDateFormats["IsoNoTimeZone"] = "yyyy-MM-dd'T'HH:mm:ss.SSS";
472
+ /**
473
+ * Standard {@link https://en.wikipedia.org/wiki/ISO_8601 | ISO-8601} format.
474
+ */ ZDateFormats["Iso"] = "yyyy-MM-dd'T'HH:mm:ss.SSSXX";
475
+ /**
476
+ * Users local date (locale specific).
477
+ */ ZDateFormats["LocalDate"] = "P";
478
+ /**
479
+ * User local time (locale specific).
480
+ */ ZDateFormats["LocalTime"] = "p";
481
+ /**
482
+ * Date and time formatted with user specific locale.
483
+ */ ZDateFormats["LocalDateTime"] = "Pp";
484
+ return ZDateFormats;
524
485
  }({});
525
486
  /**
526
- * Formats a given value.
527
- *
528
- * @param value -
529
- * The value to format.
530
- * @param options -
531
- * The given options for the format.
532
- *
533
- * @returns
534
- * If value is null or undefined, then the empty string is returned.
535
- * If value is a string, then the date is guessed from the string and
536
- * reformatted to the format specified by options. Otherwise,
537
- * the date or number specified by value is formatted to the culture,
538
- * timezone, and format specified in the options.
539
- */ function formatDateTime(value, options = {}) {
540
- const { format = "Pp", culture: culture$1 = culture(), timeZone = userTimeZone(), fallback = "" } = options;
541
- let date;
542
- if (value == null) {
543
- date = null;
544
- } else if (typeof value === "string") {
545
- date = guessDateTime(value, {
546
- ...options,
547
- fallback: null
548
- });
549
- } else {
550
- date = new Date(value);
551
- }
552
- if (date == null || Number.isNaN(date.getTime())) {
553
- return fallback;
554
- }
555
- const withTz = new tz.TZDate(date, timeZone);
556
- return dateFns.formatDate(withTz, format, {
557
- locale: LocaleLookup[culture$1]
558
- });
559
- }
560
-
561
- /**
562
- * Does replacement of interpolation, ${}, tokens in a string.
563
- *
564
- * @param tokenized -
565
- * The string that can contain interpolation tokens.
566
- * @param tokens -
567
- * The tokens to replace.
568
- *
569
- * @returns
570
- * A detokenized string that replaces the tokens with the values
571
- * in the token dictionary. If a value is missing in the token dictionary,
572
- * then the tokens are preserved. If the value of a token is null or
573
- * undefined explicitly, then any tokens in the tokenized string are
574
- * removed for that value.
575
- */ function detokenize(tokenized, tokens) {
576
- if (tokenized == null) return "";
577
- return tokenized.replace(/\$\{([^}]+)\}/g, (_, tokenName)=>{
578
- if (tokenName in tokens) {
579
- const value = tokens[tokenName];
580
- if (value === null || value === undefined) {
581
- return "";
582
- }
583
- return value;
584
- }
585
- return `\${${tokenName}}`; // leave token intact if not present in tokens
586
- });
587
- }
588
-
589
- /**
590
- * Returns true if an object is empty, null, or undefined.
591
- *
592
- * Note that this is different than lodash's isEmpty method.
593
- * Checking an empty array or empty string will result
594
- * in false.
595
- *
596
- * @param candidate -
597
- * The object to test.
598
- *
599
- * @returns
600
- * True if candidate is the empty object or
601
- * null. False otherwise.
602
- */ function isEmptyObject(candidate) {
603
- const candidateType = typeof candidate;
604
- return candidate == null || candidateType === "object" && Object.keys(candidate).length === 0;
487
+ * Formats a given value.
488
+ *
489
+ * @param value -
490
+ * The value to format.
491
+ * @param options -
492
+ * The given options for the format.
493
+ *
494
+ * @returns
495
+ * If value is null or undefined, then the empty string is returned.
496
+ * If value is a string, then the date is guessed from the string and
497
+ * reformatted to the format specified by options. Otherwise,
498
+ * the date or number specified by value is formatted to the culture,
499
+ * timezone, and format specified in the options.
500
+ */ function formatDateTime(value, options = {}) {
501
+ const { format = "Pp", culture: culture$1 = culture(), timeZone = userTimeZone(), fallback = "" } = options;
502
+ let date;
503
+ if (value == null) date = null;
504
+ else if (typeof value === "string") date = guessDateTime(value, {
505
+ ...options,
506
+ fallback: null
507
+ });
508
+ else date = new Date(value);
509
+ if (date == null || Number.isNaN(date.getTime())) return fallback;
510
+ return (0, date_fns.formatDate)(new _date_fns_tz.TZDate(date, timeZone), format, { locale: LocaleLookup[culture$1] });
605
511
  }
606
-
607
- /**
608
- * Information for an enum value.
609
- *
610
- * This is useful for front end development when
611
- * you want to map an enumeration like value to
612
- * things like a display name, description, and
613
- * avatar. ECMAScript does not support decorators
614
- * for literal fields so this is an alternative
615
- * to describe that kind of information.
616
- *
617
- * This is similar to Metadata from helpful-query,
618
- * but it's much more specific and specialized
619
- * to enumerations.
620
- */ function _define_property$6(obj, key, value) {
621
- if (key in obj) {
622
- Object.defineProperty(obj, key, {
623
- value: value,
624
- enumerable: true,
625
- configurable: true,
626
- writable: true
627
- });
628
- } else {
629
- obj[key] = value;
630
- }
631
- return obj;
512
+ //#endregion
513
+ //#region src/detokenize/detokenize.mts
514
+ /**
515
+ * Does replacement of interpolation, ${}, tokens in a string.
516
+ *
517
+ * @param tokenized -
518
+ * The string that can contain interpolation tokens.
519
+ * @param tokens -
520
+ * The tokens to replace.
521
+ *
522
+ * @returns
523
+ * A detokenized string that replaces the tokens with the values
524
+ * in the token dictionary. If a value is missing in the token dictionary,
525
+ * then the tokens are preserved. If the value of a token is null or
526
+ * undefined explicitly, then any tokens in the tokenized string are
527
+ * removed for that value.
528
+ */ function detokenize(tokenized, tokens) {
529
+ if (tokenized == null) return "";
530
+ return tokenized.replace(/\$\{([^}]+)\}/g, (_, tokenName) => {
531
+ if (tokenName in tokens) {
532
+ const value = tokens[tokenName];
533
+ if (value === null || value === void 0) return "";
534
+ return value;
535
+ }
536
+ return `\${${tokenName}}`;
537
+ });
632
538
  }
633
- /**
634
- * Builds information for an enum.
635
- */ class ZEnumInfoBuilder {
636
- /**
637
- * The display name of the enum.
638
- *
639
- * @param name -
640
- * The display name of the enum.
641
- *
642
- * @returns
643
- * This object.
644
- */ name(name) {
645
- this._metadata.name = name;
646
- return this;
647
- }
648
- /**
649
- * Text description of the enum.
650
- *
651
- * @param description -
652
- * Text description of what the value means.
653
- *
654
- * @returns
655
- * This object.
656
- */ description(description) {
657
- this._metadata.description = description;
658
- return this;
659
- }
660
- /**
661
- * The avatar representation of the enum.
662
- *
663
- * @param avatar -
664
- * The avatar representation of what the value
665
- * is. This can be anything but should be related
666
- * to the framework it is being developed for.
667
- *
668
- * @returns
669
- * This object.
670
- */ avatar(avatar) {
671
- this._metadata.avatar = avatar;
672
- return this;
673
- }
674
- /**
675
- * Returns a shallow copy of the metadata.
676
- *
677
- * @returns
678
- * A shallow copy of the metadata.
679
- */ build() {
680
- return {
681
- ...this._metadata
682
- };
683
- }
684
- /**
685
- * Initializes a new instance of this object.
686
- *
687
- * @param value -
688
- * The value to initialize with.
689
- */ constructor(value){
690
- _define_property$6(this, "_metadata", void 0);
691
- this._metadata = {
692
- value
693
- };
694
- }
539
+ //#endregion
540
+ //#region src/empty/is-empty-object.mts
541
+ /**
542
+ * Returns true if an object is empty, null, or undefined.
543
+ *
544
+ * Note that this is different than lodash's isEmpty method.
545
+ * Checking an empty array or empty string will result
546
+ * in false.
547
+ *
548
+ * @param candidate -
549
+ * The object to test.
550
+ *
551
+ * @returns
552
+ * True if candidate is the empty object or
553
+ * null. False otherwise.
554
+ */ function isEmptyObject(candidate) {
555
+ return candidate == null || typeof candidate === "object" && Object.keys(candidate).length === 0;
695
556
  }
696
-
697
- const BYTES_PER_KIBIBYTE = 1024;
698
- const BYTES_PER_MEBIBYTE = 1048576; // 1024 ^ 2
699
- const BYTES_PER_GIBIBYTE = 1073741824; // 1024 ^ 3
700
- const BYTES_PER_TEBIBYTE = 1099511627776; // 1024 ^ 4
701
- const BYTES_PER_PEBIBYTE = 1125899906842624; // 1024 ^ 5
557
+ //#endregion
558
+ //#region src/enum/enum-info.mts
559
+ /**
560
+ * Information for an enum value.
561
+ *
562
+ * This is useful for front end development when
563
+ * you want to map an enumeration like value to
564
+ * things like a display name, description, and
565
+ * avatar. ECMAScript does not support decorators
566
+ * for literal fields so this is an alternative
567
+ * to describe that kind of information.
568
+ *
569
+ * This is similar to Metadata from helpful-query,
570
+ * but it's much more specific and specialized
571
+ * to enumerations.
572
+ */ /**
573
+ * Builds information for an enum.
574
+ */ var ZEnumInfoBuilder = class {
575
+ _metadata;
576
+ /**
577
+ * Initializes a new instance of this object.
578
+ *
579
+ * @param value -
580
+ * The value to initialize with.
581
+ */ constructor(value) {
582
+ this._metadata = { value };
583
+ }
584
+ /**
585
+ * The display name of the enum.
586
+ *
587
+ * @param name -
588
+ * The display name of the enum.
589
+ *
590
+ * @returns
591
+ * This object.
592
+ */ name(name) {
593
+ this._metadata.name = name;
594
+ return this;
595
+ }
596
+ /**
597
+ * Text description of the enum.
598
+ *
599
+ * @param description -
600
+ * Text description of what the value means.
601
+ *
602
+ * @returns
603
+ * This object.
604
+ */ description(description) {
605
+ this._metadata.description = description;
606
+ return this;
607
+ }
608
+ /**
609
+ * The avatar representation of the enum.
610
+ *
611
+ * @param avatar -
612
+ * The avatar representation of what the value
613
+ * is. This can be anything but should be related
614
+ * to the framework it is being developed for.
615
+ *
616
+ * @returns
617
+ * This object.
618
+ */ avatar(avatar) {
619
+ this._metadata.avatar = avatar;
620
+ return this;
621
+ }
622
+ /**
623
+ * Returns a shallow copy of the metadata.
624
+ *
625
+ * @returns
626
+ * A shallow copy of the metadata.
627
+ */ build() {
628
+ return { ...this._metadata };
629
+ }
630
+ };
631
+ //#endregion
632
+ //#region src/file-size/file-size.mts
633
+ var BYTES_PER_KIBIBYTE = 1024;
634
+ var BYTES_PER_MEBIBYTE = 1048576;
635
+ var BYTES_PER_GIBIBYTE = 1073741824;
636
+ var BYTES_PER_TEBIBYTE = 1099511627776;
637
+ var BYTES_PER_PEBIBYTE = 0x4000000000000;
702
638
  function bytes(bytesPerUnit, amount) {
703
- return Math.ceil(bytesPerUnit * amount);
639
+ return Math.ceil(bytesPerUnit * amount);
704
640
  }
705
641
  /**
706
- * Returns the total number of bytes for the wanted amount of kibibytes.
707
- *
708
- * A kibibyte is 1024 bytes.
709
- *
710
- * @param amount -
711
- * The total number of kibibytes to convert to bytes.
712
- *
713
- * @returns
714
- * The total number of bytes in the given amount of kibibytes.
715
- */ const kibibytes = bytes.bind(null, BYTES_PER_KIBIBYTE);
716
- /**
717
- * @see {@link kibibytes}
718
- */ const kib = kibibytes;
719
- /**
720
- * Returns the total number of bytes for the wanted number of mebibytes.
721
- *
722
- * A mebibyte is 1024 kibibytes.
723
- *
724
- * @param amount -
725
- * The total amount of mebibytes to convert to bytes.
726
- *
727
- * @returns
728
- * The total number of bytes in the given amount of mebibytes.
729
- */ const mebibytes = bytes.bind(null, BYTES_PER_MEBIBYTE);
730
- /**
731
- * @see {@link mebibytes}
732
- */ const mib = mebibytes;
733
- /**
734
- * Returns the total number of bytes for the wanted number of gibibytes.
735
- *
736
- * A gibibyte is 1024 mebibytes.
737
- *
738
- * @param amount -
739
- * The total amount of gibibytes to convert to bytes.
740
- *
741
- * @returns
742
- * The total number of bytes in the given amount of gibibytes.
743
- */ const gibibytes = bytes.bind(null, BYTES_PER_GIBIBYTE);
744
- /**
745
- * @see {@link gibibytes}
746
- */ const gib = gibibytes;
747
- /**
748
- * Returns the total number of bytes for the wanted number of tebibytes.
749
- *
750
- * A tebibyte is 1024 gibibytes.
751
- *
752
- * @param amount -
753
- * The total amount of tebibytes to convert to bytes.
754
- *
755
- * @returns
756
- * The total number of bytes in the given amount of tebibytes.
757
- */ const tebibytes = bytes.bind(null, BYTES_PER_TEBIBYTE);
758
- /**
759
- * @see {@link tebibytes}
760
- */ const tib = tebibytes;
761
- /**
762
- * Returns the total number of bytes for the wanted number of pebibytes.
763
- *
764
- * A pebibytes is 1024 tebibytes.
765
- *
766
- * @param amount -
767
- * The total amount of pebibytes to convert to bytes.
768
- *
769
- * @returns
770
- * The total number of bytes in the given amount of pebibytes.
771
- */ const pebibytes = bytes.bind(null, BYTES_PER_PEBIBYTE);
772
- /**
773
- * @see {@link pebibytes}
774
- */ const pib = pebibytes;
775
-
776
- /**
777
- * Returns the first value in an argument list that matches a predicate.
778
- *
779
- * @param predicate -
780
- * The match method against each value argument.
781
- * @param fallback -
782
- * The fallback value in the case that all arguments fail
783
- * the predicate.
784
- * @param first -
785
- * The first value to check.
786
- * @param remaining -
787
- * The remaining values beyond the first to check.
788
- * @param T -
789
- * The type of data that will be enumerated.
790
- *
791
- * @returns
792
- * The first value for where predicate returns true for the given argument value.
793
- * If first and all values of remaining fail the predicate then fallback is returned.
794
- */ function firstWhere(predicate, fallback, first, ...remaining) {
795
- if (predicate(first)) {
796
- return first;
797
- }
798
- for(let i = 0; i < remaining.length; ++i){
799
- const val = remaining[i];
800
- if (predicate(val)) {
801
- return val;
802
- }
803
- }
804
- return fallback;
805
- }
806
- /**
807
- * Returns the first value in args such that args is not null or undefined.
808
- *
809
- * @param fallback -
810
- * The fallback value in the case that all values in args are null/undefined.
811
- * @param first -
812
- * The first value to check.
813
- * @param remaining -
814
- * The remaining values beyond the first to check.
815
- * @param T -
816
- * The type of data that will be enumerated.
817
- *
818
- * @returns
819
- * The first value if it is not null or undefined. If first is undefined or null, then the first item
820
- * in remaining such that remaining[i] is not null or undefined is returned. If first and all values of
821
- * remaining are null or undefined, then fallback is returned.
822
- *
823
- * @example
824
- *
825
- * ```ts
826
- * // 'Defined'
827
- * const shouldBeDefined = firstDefined('Fallback', null, undefined, 'Defined');
828
- * // 'Fallback'
829
- * const shouldBeFallback = firstDefined('Fallback', null, undefined);
830
- * const shouldAlsoBeFallback = firstDefined('Fallback', undefined);
831
- * // 'First'
832
- * const shouldBeFirst = firstDefined('Fallback', 'First', null, 'Third');
833
- * ```
834
- */ function firstDefined(fallback, first, ...remaining) {
835
- return firstWhere((v)=>v != null, fallback, first, ...remaining);
642
+ * Returns the total number of bytes for the wanted amount of kibibytes.
643
+ *
644
+ * A kibibyte is 1024 bytes.
645
+ *
646
+ * @param amount -
647
+ * The total number of kibibytes to convert to bytes.
648
+ *
649
+ * @returns
650
+ * The total number of bytes in the given amount of kibibytes.
651
+ */ var kibibytes = bytes.bind(null, BYTES_PER_KIBIBYTE);
652
+ /**
653
+ * @see {@link kibibytes}
654
+ */ var kib = kibibytes;
655
+ /**
656
+ * Returns the total number of bytes for the wanted number of mebibytes.
657
+ *
658
+ * A mebibyte is 1024 kibibytes.
659
+ *
660
+ * @param amount -
661
+ * The total amount of mebibytes to convert to bytes.
662
+ *
663
+ * @returns
664
+ * The total number of bytes in the given amount of mebibytes.
665
+ */ var mebibytes = bytes.bind(null, BYTES_PER_MEBIBYTE);
666
+ /**
667
+ * @see {@link mebibytes}
668
+ */ var mib = mebibytes;
669
+ /**
670
+ * Returns the total number of bytes for the wanted number of gibibytes.
671
+ *
672
+ * A gibibyte is 1024 mebibytes.
673
+ *
674
+ * @param amount -
675
+ * The total amount of gibibytes to convert to bytes.
676
+ *
677
+ * @returns
678
+ * The total number of bytes in the given amount of gibibytes.
679
+ */ var gibibytes = bytes.bind(null, BYTES_PER_GIBIBYTE);
680
+ /**
681
+ * @see {@link gibibytes}
682
+ */ var gib = gibibytes;
683
+ /**
684
+ * Returns the total number of bytes for the wanted number of tebibytes.
685
+ *
686
+ * A tebibyte is 1024 gibibytes.
687
+ *
688
+ * @param amount -
689
+ * The total amount of tebibytes to convert to bytes.
690
+ *
691
+ * @returns
692
+ * The total number of bytes in the given amount of tebibytes.
693
+ */ var tebibytes = bytes.bind(null, BYTES_PER_TEBIBYTE);
694
+ /**
695
+ * @see {@link tebibytes}
696
+ */ var tib = tebibytes;
697
+ /**
698
+ * Returns the total number of bytes for the wanted number of pebibytes.
699
+ *
700
+ * A pebibytes is 1024 tebibytes.
701
+ *
702
+ * @param amount -
703
+ * The total amount of pebibytes to convert to bytes.
704
+ *
705
+ * @returns
706
+ * The total number of bytes in the given amount of pebibytes.
707
+ */ var pebibytes = bytes.bind(null, BYTES_PER_PEBIBYTE);
708
+ /**
709
+ * @see {@link pebibytes}
710
+ */ var pib = pebibytes;
711
+ //#endregion
712
+ //#region src/first-where/first-where.mts
713
+ /**
714
+ * Returns the first value in an argument list that matches a predicate.
715
+ *
716
+ * @param predicate -
717
+ * The match method against each value argument.
718
+ * @param fallback -
719
+ * The fallback value in the case that all arguments fail
720
+ * the predicate.
721
+ * @param first -
722
+ * The first value to check.
723
+ * @param remaining -
724
+ * The remaining values beyond the first to check.
725
+ * @param T -
726
+ * The type of data that will be enumerated.
727
+ *
728
+ * @returns
729
+ * The first value for where predicate returns true for the given argument value.
730
+ * If first and all values of remaining fail the predicate then fallback is returned.
731
+ */ function firstWhere(predicate, fallback, first, ...remaining) {
732
+ if (predicate(first)) return first;
733
+ for (let i = 0; i < remaining.length; ++i) {
734
+ const val = remaining[i];
735
+ if (predicate(val)) return val;
736
+ }
737
+ return fallback;
836
738
  }
837
739
  /**
838
- * Returns the first value in args such that args is truthy
839
- *
840
- * @param fallback -
841
- * The fallback value in the case that all values in args are falsy.
842
- * @param first -
843
- * The first value to check.
844
- * @param remaining -
845
- * The remaining values beyond the first to check.
846
- * @param T -
847
- * The type of data that will be enumerated.
848
- *
849
- * @returns
850
- * The first value if it is truthy. If first is falsy, then the first item
851
- * in remaining such that remaining[i] is truthy is returned. If first and
852
- * all values of remaining are falsy, then fallback is returned.
853
- *
854
- * @example
855
- *
856
- * ```ts
857
- * // 'Defined'
858
- * const shouldBeDefined = firstTruthy('Fallback', null, undefined, 'Defined');
859
- * // 'Fallback'
860
- * const shouldBeFallback = firstTruthy('Fallback', '', undefined);
861
- * const shouldAlsoBeFallback = firstDefined('Fallback', 0, false);
862
- * // 'First'
863
- * const shouldBeFirst = firstDefined('Fallback', 'First', null, false, 0, NaN);
864
- * ```
865
- */ function firstTruthy(fallback, first, ...remaining) {
866
- return firstWhere((v)=>!!v, fallback, first, ...remaining);
867
- }
868
-
869
- function _define_property$5(obj, key, value) {
870
- if (key in obj) {
871
- Object.defineProperty(obj, key, {
872
- value: value,
873
- enumerable: true,
874
- configurable: true,
875
- writable: true
876
- });
877
- } else {
878
- obj[key] = value;
879
- }
880
- return obj;
740
+ * Returns the first value in args such that args is not null or undefined.
741
+ *
742
+ * @param fallback -
743
+ * The fallback value in the case that all values in args are null/undefined.
744
+ * @param first -
745
+ * The first value to check.
746
+ * @param remaining -
747
+ * The remaining values beyond the first to check.
748
+ * @param T -
749
+ * The type of data that will be enumerated.
750
+ *
751
+ * @returns
752
+ * The first value if it is not null or undefined. If first is undefined or null, then the first item
753
+ * in remaining such that remaining[i] is not null or undefined is returned. If first and all values of
754
+ * remaining are null or undefined, then fallback is returned.
755
+ *
756
+ * @example
757
+ *
758
+ * ```ts
759
+ * // 'Defined'
760
+ * const shouldBeDefined = firstDefined('Fallback', null, undefined, 'Defined');
761
+ * // 'Fallback'
762
+ * const shouldBeFallback = firstDefined('Fallback', null, undefined);
763
+ * const shouldAlsoBeFallback = firstDefined('Fallback', undefined);
764
+ * // 'First'
765
+ * const shouldBeFirst = firstDefined('Fallback', 'First', null, 'Third');
766
+ * ```
767
+ */ function firstDefined(fallback, first, ...remaining) {
768
+ return firstWhere((v) => v != null, fallback, first, ...remaining);
881
769
  }
882
770
  /**
883
- * An object that can be used to build an {@link IZQuadrilateralCorners} object.
884
- *
885
- * @param T -
886
- * The type of data to associate to each corner.
887
- */ class ZQuadrilateralCornersBuilder {
888
- /**
889
- * Sets the bottom left corner value.
890
- *
891
- * @param value -
892
- * The value to set.
893
- *
894
- * @returns
895
- * This object.
896
- */ bottomLeft(value) {
897
- this._corners.bottomLeft = value;
898
- return this;
899
- }
900
- /**
901
- * Sets the bottom right corner value.
902
- *
903
- * @param value -
904
- * The value to set.
905
- *
906
- * @returns
907
- * This object.
908
- */ bottomRight(value) {
909
- this._corners.bottomRight = value;
910
- return this;
911
- }
912
- /**
913
- * Sets the top left corner value.
914
- *
915
- * @param value -
916
- * The value to set.
917
- *
918
- * @returns
919
- * This object.
920
- */ topLeft(value) {
921
- this._corners.topLeft = value;
922
- return this;
923
- }
924
- /**
925
- * Sets the top right corner value.
926
- *
927
- * @param value -
928
- * The value to set.
929
- *
930
- * @returns
931
- * This object.
932
- */ topRight(value) {
933
- this._corners.topRight = value;
934
- return this;
935
- }
936
- /**
937
- * Sets the bottom left and bottom right values.
938
- *
939
- * @param value -
940
- * The value for bottom left and bottom right.
941
- *
942
- * @returns
943
- * This object.
944
- */ bottom(value) {
945
- return this.bottomLeft(value).bottomRight(value);
946
- }
947
- /**
948
- * Sets the bottom left and top left values.
949
- *
950
- * @param value -
951
- * The value for bottom left and top left.
952
- *
953
- * @returns
954
- * This object.
955
- */ left(value) {
956
- return this.topLeft(value).bottomLeft(value);
957
- }
958
- /**
959
- * Sets the bottom right and top right values.
960
- *
961
- * @param value -
962
- * The value for bottom right and top right.
963
- *
964
- * @returns
965
- * This object.
966
- */ right(value) {
967
- return this.bottomRight(value).topRight(value);
968
- }
969
- /**
970
- * Sets the top left and top right values.
971
- *
972
- * @param value -
973
- * The value for top left and top right.
974
- *
975
- * @returns
976
- * This object.
977
- */ top(value) {
978
- return this.topLeft(value).topRight(value);
979
- }
980
- /**
981
- * Sets the corner values based on an object that
982
- * describes a set of quadrilateral corners.
983
- *
984
- * @param other -
985
- * The object that describes the corners.
986
- *
987
- * @returns
988
- * This object.
989
- */ from(other) {
990
- function isVerticals(candidate) {
991
- return candidate != null && (Object.prototype.hasOwnProperty.call(candidate, "bottom") || Object.prototype.hasOwnProperty.call(candidate, "top"));
992
- }
993
- function isHorizontals(candidate) {
994
- return candidate != null && (Object.prototype.hasOwnProperty.call(candidate, "left") || Object.prototype.hasOwnProperty.call(candidate, "right"));
995
- }
996
- function isCorners(candidate) {
997
- return candidate != null && (Object.prototype.hasOwnProperty.call(candidate, "bottomLeft") || Object.prototype.hasOwnProperty.call(candidate, "bottomRight") || Object.prototype.hasOwnProperty.call(candidate, "topLeft") || Object.prototype.hasOwnProperty.call(candidate, "topRight"));
998
- }
999
- const { bottomLeft, bottomRight, topLeft, topRight } = this._corners;
1000
- if (isCorners(other)) {
1001
- this._corners.bottomLeft = firstDefined(bottomLeft, other.bottomLeft);
1002
- this._corners.bottomRight = firstDefined(bottomRight, other.bottomRight);
1003
- this._corners.topLeft = firstDefined(topLeft, other.topLeft);
1004
- this._corners.topRight = firstDefined(topRight, other.topRight);
1005
- return this;
1006
- }
1007
- if (isVerticals(other)) {
1008
- this._corners.bottomLeft = firstDefined(bottomLeft, other.bottom);
1009
- this._corners.bottomRight = firstDefined(bottomRight, other.bottom);
1010
- this._corners.topLeft = firstDefined(topLeft, other.top);
1011
- this._corners.topRight = firstDefined(topRight, other.top);
1012
- return this;
1013
- }
1014
- if (isHorizontals(other)) {
1015
- this._corners.bottomLeft = firstDefined(bottomLeft, other.left);
1016
- this._corners.bottomRight = firstDefined(bottomRight, other.right);
1017
- this._corners.topLeft = firstDefined(topLeft, other.left);
1018
- this._corners.topRight = firstDefined(topRight, other.right);
1019
- return this;
1020
- }
1021
- if (!isEmptyObject(other)) {
1022
- this._corners.bottomLeft = firstDefined(bottomLeft, other);
1023
- this._corners.bottomRight = firstDefined(bottomRight, other);
1024
- this._corners.topLeft = firstDefined(topLeft, other);
1025
- this._corners.topRight = firstDefined(topRight, other);
1026
- }
1027
- return this;
1028
- }
1029
- /**
1030
- * Copies another corners object into this builder.
1031
- *
1032
- * @param other -
1033
- * The corners object to copy.
1034
- *
1035
- * @returns
1036
- * This object.
1037
- */ copy(other) {
1038
- this._corners = structuredClone(other);
1039
- return this;
1040
- }
1041
- /**
1042
- * Builds the corners.
1043
- *
1044
- * @returns
1045
- * The built corners.
1046
- */ build() {
1047
- return structuredClone(this._corners);
1048
- }
1049
- constructor(start){
1050
- _define_property$5(this, "_corners", void 0);
1051
- this._corners = {
1052
- bottomLeft: start,
1053
- bottomRight: start,
1054
- topLeft: start,
1055
- topRight: start
1056
- };
1057
- }
771
+ * Returns the first value in args such that args is truthy
772
+ *
773
+ * @param fallback -
774
+ * The fallback value in the case that all values in args are falsy.
775
+ * @param first -
776
+ * The first value to check.
777
+ * @param remaining -
778
+ * The remaining values beyond the first to check.
779
+ * @param T -
780
+ * The type of data that will be enumerated.
781
+ *
782
+ * @returns
783
+ * The first value if it is truthy. If first is falsy, then the first item
784
+ * in remaining such that remaining[i] is truthy is returned. If first and
785
+ * all values of remaining are falsy, then fallback is returned.
786
+ *
787
+ * @example
788
+ *
789
+ * ```ts
790
+ * // 'Defined'
791
+ * const shouldBeDefined = firstTruthy('Fallback', null, undefined, 'Defined');
792
+ * // 'Fallback'
793
+ * const shouldBeFallback = firstTruthy('Fallback', '', undefined);
794
+ * const shouldAlsoBeFallback = firstDefined('Fallback', 0, false);
795
+ * // 'First'
796
+ * const shouldBeFirst = firstDefined('Fallback', 'First', null, false, 0, NaN);
797
+ * ```
798
+ */ function firstTruthy(fallback, first, ...remaining) {
799
+ return firstWhere((v) => !!v, fallback, first, ...remaining);
1058
800
  }
1059
-
1060
- function _define_property$4(obj, key, value) {
1061
- if (key in obj) {
1062
- Object.defineProperty(obj, key, {
1063
- value: value,
1064
- enumerable: true,
1065
- configurable: true,
1066
- writable: true
1067
- });
1068
- } else {
1069
- obj[key] = value;
1070
- }
1071
- return obj;
1072
- }
1073
- /**
1074
- * Represents a builder for a quadrilateral object.
1075
- */ class ZQuadrilateralBuilder {
1076
- /**
1077
- * Sets the bottom value.
1078
- *
1079
- * @param bottom -
1080
- * The bottom value.
1081
- *
1082
- * @returns
1083
- * This object.
1084
- */ bottom(bottom) {
1085
- this._quad.bottom = bottom;
1086
- return this;
1087
- }
1088
- /**
1089
- * Sets the left value.
1090
- *
1091
- * @param left -
1092
- * The left value.
1093
- *
1094
- * @returns
1095
- * This object.
1096
- */ left(left) {
1097
- this._quad.left = left;
1098
- return this;
1099
- }
1100
- /**
1101
- * Sets the right value.
1102
- *
1103
- * @param right -
1104
- * The right value.
1105
- *
1106
- * @returns
1107
- * This object.
1108
- */ right(right) {
1109
- this._quad.right = right;
1110
- return this;
1111
- }
1112
- /**
1113
- * Sets the top value.
1114
- *
1115
- * @param top -
1116
- * The top value.
1117
- *
1118
- * @returns
1119
- * This object.
1120
- */ top(top) {
1121
- this._quad.top = top;
1122
- return this;
1123
- }
1124
- /**
1125
- * Sets the left and right value.
1126
- *
1127
- * @param x -
1128
- * The left and right value.
1129
- *
1130
- * @returns
1131
- * This object.
1132
- */ x(x) {
1133
- return this.left(x).right(x);
1134
- }
1135
- /**
1136
- * Sets the top and bottom value.
1137
- *
1138
- * @param y -
1139
- * The top and bottom value.
1140
- *
1141
- * @returns
1142
- * This object.
1143
- */ y(y) {
1144
- return this.bottom(y).top(y);
1145
- }
1146
- /**
1147
- * Constructs a full quadrilateral from an object that describes a quadrilateral.
1148
- *
1149
- * Note the limitations of this method. If T is of type Quadrilateral or Point2d,
1150
- * then this method's behavior is undefined and it will most likely build a
1151
- * corrupt object.
1152
- *
1153
- * @param other -
1154
- * The object to build from.
1155
- *
1156
- * @returns
1157
- * This object.
1158
- */ from(other) {
1159
- function isPoint2d(candidate) {
1160
- return candidate != null && (Object.prototype.hasOwnProperty.call(candidate, "x") || Object.prototype.hasOwnProperty.call(candidate, "y"));
1161
- }
1162
- function isQuadrilateral(candidate) {
1163
- return candidate != null && (Object.prototype.hasOwnProperty.call(candidate, "bottom") || Object.prototype.hasOwnProperty.call(candidate, "left") || Object.prototype.hasOwnProperty.call(candidate, "right") || Object.prototype.hasOwnProperty.call(candidate, "top"));
1164
- }
1165
- if (isQuadrilateral(other)) {
1166
- this._quad.bottom = firstDefined(this._quad.bottom, other.bottom);
1167
- this._quad.left = firstDefined(this._quad.left, other.left);
1168
- this._quad.right = firstDefined(this._quad.right, other.right);
1169
- this._quad.top = firstDefined(this._quad.top, other.top);
1170
- return this;
1171
- }
1172
- if (isPoint2d(other)) {
1173
- this._quad.bottom = firstDefined(this._quad.bottom, other.y);
1174
- this._quad.left = firstDefined(this._quad.left, other.x);
1175
- this._quad.right = firstDefined(this._quad.right, other.x);
1176
- this._quad.top = firstDefined(this._quad.top, other.y);
1177
- return this;
1178
- }
1179
- if (!isEmptyObject(other)) {
1180
- this._quad.bottom = firstDefined(this._quad.bottom, other);
1181
- this._quad.left = firstDefined(this._quad.left, other);
1182
- this._quad.right = firstDefined(this._quad.right, other);
1183
- this._quad.top = firstDefined(this._quad.top, other);
1184
- }
1185
- return this;
1186
- }
1187
- /**
1188
- * Copies another quadrilateral object into the current instance.
1189
- *
1190
- * @param other -
1191
- * The quadrilateral object to copy.
1192
- *
1193
- * @returns
1194
- * This object.
1195
- */ copy(other) {
1196
- // The copy is done this way instead of a structured
1197
- // copy because we want to support things like
1198
- // copy(other.getBoundingClientRect()) which
1199
- // is immutable when working on the client.
1200
- this._quad.left = other.left;
1201
- this._quad.right = other.right;
1202
- this._quad.top = other.top;
1203
- this._quad.bottom = other.bottom;
1204
- return this;
1205
- }
1206
- /**
1207
- * Returns the built quadrilateral object.
1208
- *
1209
- * @returns
1210
- * The built quadrilateral.
1211
- */ build() {
1212
- return structuredClone(this._quad);
1213
- }
1214
- /**
1215
- * Initializes a new instance of this object.
1216
- *
1217
- * @param start -
1218
- * The starting value.
1219
- */ constructor(start){
1220
- _define_property$4(this, "_quad", void 0);
1221
- this._quad = {
1222
- bottom: start,
1223
- left: start,
1224
- right: start,
1225
- top: start
1226
- };
1227
- }
1228
- }
1229
-
1230
- function _define_property$3(obj, key, value) {
1231
- if (key in obj) {
1232
- Object.defineProperty(obj, key, {
1233
- value: value,
1234
- enumerable: true,
1235
- configurable: true,
1236
- writable: true
1237
- });
1238
- } else {
1239
- obj[key] = value;
1240
- }
1241
- return obj;
1242
- }
1243
- /**
1244
- * Represents a helper object that can run calculations on a numeric quadrilateral.
1245
- */ class ZRectangle {
1246
- /**
1247
- * Calculates the width of the rectangle.
1248
- *
1249
- * @returns
1250
- * The numeric width of the rectangle.
1251
- */ width() {
1252
- const { left, right } = this.sides;
1253
- return right - left;
1254
- }
1255
- /**
1256
- * Calculates the height of the rectangle.
1257
- *
1258
- * @returns
1259
- * The numeric height of the rectangle.
1260
- */ height() {
1261
- const { top, bottom } = this.sides;
1262
- return bottom - top;
1263
- }
1264
- /**
1265
- * Calculates the area of the rectangle.
1266
- *
1267
- * @returns
1268
- * The numeric area of the rectangle.
1269
- */ area() {
1270
- return this.width() * this.height();
1271
- }
1272
- /**
1273
- * Takes a candidate and attaches it to this rectangle that matches the anchor points.
1274
- *
1275
- * @param anchor -
1276
- * The anchor point of this rectangle.
1277
- * @param candidate -
1278
- * The candidate rectangle to move
1279
- * @param candidateAnchor -
1280
- * The anchor point of the candidate rectangle.
1281
- *
1282
- * @returns
1283
- * A new quadrilateral that has it's placement such that if candidate was moved
1284
- * to this resulting position, would have its candidateAnchor be in the same
1285
- * place as this rectangles specified anchor.
1286
- */ attach(anchor, candidate, candidateAnchor) {
1287
- const _candidate = new ZRectangle(candidate);
1288
- const { x: ax, y: ay } = this.point(anchor);
1289
- const { x: ox, y: oy } = new ZRectangle(candidate).point(candidateAnchor);
1290
- const left = candidate.left + (ax - ox);
1291
- const top = candidate.top + (ay - oy);
1292
- const bottom = top + _candidate.height();
1293
- const right = left + _candidate.width();
1294
- return new ZQuadrilateralBuilder(0).left(left).right(right).top(top).bottom(bottom).build();
1295
- }
1296
- /**
1297
- * Takes the candidate quadrilateral and adjusts it's coordinates to fit inside this rectangle.
1298
- *
1299
- * This is done by shifting the rectangle left, right, up, and down to make sure it is bounded
1300
- * inside.
1301
- *
1302
- * If the candidate width or height is larger than this rectangle, thus it cannot fit, then
1303
- * the candidate will be centered on the dimension where it is too big to fit.
1304
- *
1305
- * @param candidate -
1306
- * The candidate quadrilateral to fit.
1307
- *
1308
- * @returns
1309
- * A new quadrilateral that offsets candidate so that it can fit inside this
1310
- * rectangle.
1311
- */ offsetToFit(candidate) {
1312
- let _candidate = candidate;
1313
- const candidateRectangle = new ZRectangle(candidate);
1314
- if (candidateRectangle.width() > this.width()) {
1315
- // Center the horizontal
1316
- const { x: cx } = candidateRectangle.middleCenter();
1317
- const { x: tx } = this.middleCenter();
1318
- _candidate = new ZQuadrilateralBuilder(0).copy(_candidate).left(_candidate.left - (cx - tx)).right(_candidate.right - (cx - tx)).build();
1319
- } else {
1320
- if (_candidate.left < this.sides.left) {
1321
- // Move the candidate to the right.
1322
- _candidate = new ZQuadrilateralBuilder(0).copy(_candidate).left(this.sides.left).right(_candidate.right + (this.sides.left - _candidate.left)).build();
1323
- }
1324
- if (_candidate.right > this.sides.right) {
1325
- // Move the candidate to the left.
1326
- _candidate = new ZQuadrilateralBuilder(0).copy(_candidate).right(this.sides.right).left(_candidate.left - (_candidate.right - this.sides.right)).build();
1327
- }
1328
- }
1329
- if (candidateRectangle.height() > this.height()) {
1330
- // Center the vertical
1331
- const { y: cy } = candidateRectangle.middleCenter();
1332
- const { y: ty } = this.middleCenter();
1333
- _candidate = new ZQuadrilateralBuilder(0).copy(_candidate).top(_candidate.top - (cy - ty)).bottom(_candidate.bottom - (cy - ty)).build();
1334
- } else {
1335
- if (_candidate.bottom > this.sides.bottom) {
1336
- // Move the candidate up.
1337
- _candidate = new ZQuadrilateralBuilder(0).copy(_candidate).bottom(this.sides.bottom).top(_candidate.top - (_candidate.bottom - this.sides.bottom)).build();
1338
- }
1339
- if (_candidate.top < this.sides.top) {
1340
- // Move the candidate down
1341
- _candidate = new ZQuadrilateralBuilder(0).copy(_candidate).top(this.sides.top).bottom(_candidate.bottom + (this.sides.top - _candidate.top)).build();
1342
- }
1343
- }
1344
- return _candidate;
1345
- }
1346
- /**
1347
- * Calculates the (x, y) point given an anchor target.
1348
- *
1349
- * @param anchor -
1350
- * The anchor target to calculate the point for.
1351
- *
1352
- * @returns
1353
- * The numeric width of the rectangle.
1354
- */ point(anchor) {
1355
- const { bottom, left, right, top } = this.sides;
1356
- const [vertical, horizontal] = anchor;
1357
- const v = {
1358
- [ZVerticalAnchor.Top]: top,
1359
- [ZVerticalAnchor.Middle]: (bottom + top) / 2,
1360
- [ZVerticalAnchor.Bottom]: bottom
1361
- };
1362
- const h = {
1363
- [ZHorizontalAnchor.Left]: left,
1364
- [ZHorizontalAnchor.Center]: (right + left) / 2,
1365
- [ZHorizontalAnchor.Right]: right
1366
- };
1367
- return {
1368
- x: h[horizontal],
1369
- y: v[vertical]
1370
- };
1371
- }
1372
- /**
1373
- * Initializes a new instance of this object.
1374
- *
1375
- * @param sides -
1376
- * The numeric sides of a quadrilateral.
1377
- */ constructor(sides){
1378
- _define_property$3(this, "sides", void 0);
1379
- /**
1380
- * Calculates the top left point of the rectangle.
1381
- *
1382
- * @returns
1383
- * The top left point of the rectangle.
1384
- */ _define_property$3(this, "topLeft", void 0);
1385
- /**
1386
- * Calculates the top center point of the rectangle.
1387
- *
1388
- * @returns
1389
- * The top center point of the rectangle.
1390
- */ _define_property$3(this, "topCenter", void 0);
1391
- /**
1392
- * Calculates the top right point of the rectangle.
1393
- *
1394
- * @returns
1395
- * The top right point of the rectangle.
1396
- */ _define_property$3(this, "topRight", void 0);
1397
- /**
1398
- * Calculates the middle left point of the rectangle.
1399
- *
1400
- * @returns
1401
- * The middle left point of the rectangle.
1402
- */ _define_property$3(this, "middleLeft", void 0);
1403
- /**
1404
- * Calculates the middle center point of the rectangle.
1405
- *
1406
- * @returns
1407
- * The middle center point of the rectangle.
1408
- */ _define_property$3(this, "middleCenter", void 0);
1409
- /**
1410
- * Calculates the middle right point of the rectangle.
1411
- *
1412
- * @returns
1413
- * The middle right point of the rectangle.
1414
- */ _define_property$3(this, "middleRight", void 0);
1415
- /**
1416
- * Calculates the bottom left point of the rectangle.
1417
- *
1418
- * @returns
1419
- * The bottom left point of the rectangle.
1420
- */ _define_property$3(this, "bottomLeft", void 0);
1421
- /**
1422
- * Calculates the bottom center point of the rectangle.
1423
- *
1424
- * @returns
1425
- * The bottom center point of the rectangle.
1426
- */ _define_property$3(this, "bottomCenter", void 0);
1427
- /**
1428
- * Calculates the bottom right point of the rectangle.
1429
- *
1430
- * @returns
1431
- * The bottom right point of the rectangle.
1432
- */ _define_property$3(this, "bottomRight", void 0);
1433
- this.sides = sides;
1434
- this.topLeft = this.point.bind(this, [
1435
- ZVerticalAnchor.Top,
1436
- ZHorizontalAnchor.Left
1437
- ]);
1438
- this.topCenter = this.point.bind(this, [
1439
- ZVerticalAnchor.Top,
1440
- ZHorizontalAnchor.Center
1441
- ]);
1442
- this.topRight = this.point.bind(this, [
1443
- ZVerticalAnchor.Top,
1444
- ZHorizontalAnchor.Right
1445
- ]);
1446
- this.middleLeft = this.point.bind(this, [
1447
- ZVerticalAnchor.Middle,
1448
- ZHorizontalAnchor.Left
1449
- ]);
1450
- this.middleCenter = this.point.bind(this, [
1451
- ZVerticalAnchor.Middle,
1452
- ZHorizontalAnchor.Center
1453
- ]);
1454
- this.middleRight = this.point.bind(this, [
1455
- ZVerticalAnchor.Middle,
1456
- ZHorizontalAnchor.Right
1457
- ]);
1458
- this.bottomLeft = this.point.bind(this, [
1459
- ZVerticalAnchor.Bottom,
1460
- ZHorizontalAnchor.Left
1461
- ]);
1462
- this.bottomCenter = this.point.bind(this, [
1463
- ZVerticalAnchor.Bottom,
1464
- ZHorizontalAnchor.Center
1465
- ]);
1466
- this.bottomRight = this.point.bind(this, [
1467
- ZVerticalAnchor.Bottom,
1468
- ZHorizontalAnchor.Right
1469
- ]);
1470
- }
1471
- }
1472
-
801
+ //#endregion
802
+ //#region src/geometry/quadrilateral.mts
803
+ /**
804
+ * Represents a builder for a quadrilateral object.
805
+ */ var ZQuadrilateralBuilder = class {
806
+ _quad;
807
+ /**
808
+ * Initializes a new instance of this object.
809
+ *
810
+ * @param start -
811
+ * The starting value.
812
+ */ constructor(start) {
813
+ this._quad = {
814
+ bottom: start,
815
+ left: start,
816
+ right: start,
817
+ top: start
818
+ };
819
+ }
820
+ /**
821
+ * Sets the bottom value.
822
+ *
823
+ * @param bottom -
824
+ * The bottom value.
825
+ *
826
+ * @returns
827
+ * This object.
828
+ */ bottom(bottom) {
829
+ this._quad.bottom = bottom;
830
+ return this;
831
+ }
832
+ /**
833
+ * Sets the left value.
834
+ *
835
+ * @param left -
836
+ * The left value.
837
+ *
838
+ * @returns
839
+ * This object.
840
+ */ left(left) {
841
+ this._quad.left = left;
842
+ return this;
843
+ }
844
+ /**
845
+ * Sets the right value.
846
+ *
847
+ * @param right -
848
+ * The right value.
849
+ *
850
+ * @returns
851
+ * This object.
852
+ */ right(right) {
853
+ this._quad.right = right;
854
+ return this;
855
+ }
856
+ /**
857
+ * Sets the top value.
858
+ *
859
+ * @param top -
860
+ * The top value.
861
+ *
862
+ * @returns
863
+ * This object.
864
+ */ top(top) {
865
+ this._quad.top = top;
866
+ return this;
867
+ }
868
+ /**
869
+ * Sets the left and right value.
870
+ *
871
+ * @param x -
872
+ * The left and right value.
873
+ *
874
+ * @returns
875
+ * This object.
876
+ */ x(x) {
877
+ return this.left(x).right(x);
878
+ }
879
+ /**
880
+ * Sets the top and bottom value.
881
+ *
882
+ * @param y -
883
+ * The top and bottom value.
884
+ *
885
+ * @returns
886
+ * This object.
887
+ */ y(y) {
888
+ return this.bottom(y).top(y);
889
+ }
890
+ /**
891
+ * Constructs a full quadrilateral from an object that describes a quadrilateral.
892
+ *
893
+ * Note the limitations of this method. If T is of type Quadrilateral or Point2d,
894
+ * then this method's behavior is undefined and it will most likely build a
895
+ * corrupt object.
896
+ *
897
+ * @param other -
898
+ * The object to build from.
899
+ *
900
+ * @returns
901
+ * This object.
902
+ */ from(other) {
903
+ function isPoint2d(candidate) {
904
+ return candidate != null && (Object.prototype.hasOwnProperty.call(candidate, "x") || Object.prototype.hasOwnProperty.call(candidate, "y"));
905
+ }
906
+ function isQuadrilateral(candidate) {
907
+ return candidate != null && (Object.prototype.hasOwnProperty.call(candidate, "bottom") || Object.prototype.hasOwnProperty.call(candidate, "left") || Object.prototype.hasOwnProperty.call(candidate, "right") || Object.prototype.hasOwnProperty.call(candidate, "top"));
908
+ }
909
+ if (isQuadrilateral(other)) {
910
+ this._quad.bottom = firstDefined(this._quad.bottom, other.bottom);
911
+ this._quad.left = firstDefined(this._quad.left, other.left);
912
+ this._quad.right = firstDefined(this._quad.right, other.right);
913
+ this._quad.top = firstDefined(this._quad.top, other.top);
914
+ return this;
915
+ }
916
+ if (isPoint2d(other)) {
917
+ this._quad.bottom = firstDefined(this._quad.bottom, other.y);
918
+ this._quad.left = firstDefined(this._quad.left, other.x);
919
+ this._quad.right = firstDefined(this._quad.right, other.x);
920
+ this._quad.top = firstDefined(this._quad.top, other.y);
921
+ return this;
922
+ }
923
+ if (!isEmptyObject(other)) {
924
+ this._quad.bottom = firstDefined(this._quad.bottom, other);
925
+ this._quad.left = firstDefined(this._quad.left, other);
926
+ this._quad.right = firstDefined(this._quad.right, other);
927
+ this._quad.top = firstDefined(this._quad.top, other);
928
+ }
929
+ return this;
930
+ }
931
+ /**
932
+ * Copies another quadrilateral object into the current instance.
933
+ *
934
+ * @param other -
935
+ * The quadrilateral object to copy.
936
+ *
937
+ * @returns
938
+ * This object.
939
+ */ copy(other) {
940
+ this._quad.left = other.left;
941
+ this._quad.right = other.right;
942
+ this._quad.top = other.top;
943
+ this._quad.bottom = other.bottom;
944
+ return this;
945
+ }
946
+ /**
947
+ * Returns the built quadrilateral object.
948
+ *
949
+ * @returns
950
+ * The built quadrilateral.
951
+ */ build() {
952
+ return structuredClone(this._quad);
953
+ }
954
+ };
955
+ //#endregion
956
+ //#region src/geometry/quadrilateral-corners.mts
957
+ /**
958
+ * An object that can be used to build an {@link IZQuadrilateralCorners} object.
959
+ *
960
+ * @param T -
961
+ * The type of data to associate to each corner.
962
+ */ var ZQuadrilateralCornersBuilder = class {
963
+ _corners;
964
+ constructor(start) {
965
+ this._corners = {
966
+ bottomLeft: start,
967
+ bottomRight: start,
968
+ topLeft: start,
969
+ topRight: start
970
+ };
971
+ }
972
+ /**
973
+ * Sets the bottom left corner value.
974
+ *
975
+ * @param value -
976
+ * The value to set.
977
+ *
978
+ * @returns
979
+ * This object.
980
+ */ bottomLeft(value) {
981
+ this._corners.bottomLeft = value;
982
+ return this;
983
+ }
984
+ /**
985
+ * Sets the bottom right corner value.
986
+ *
987
+ * @param value -
988
+ * The value to set.
989
+ *
990
+ * @returns
991
+ * This object.
992
+ */ bottomRight(value) {
993
+ this._corners.bottomRight = value;
994
+ return this;
995
+ }
996
+ /**
997
+ * Sets the top left corner value.
998
+ *
999
+ * @param value -
1000
+ * The value to set.
1001
+ *
1002
+ * @returns
1003
+ * This object.
1004
+ */ topLeft(value) {
1005
+ this._corners.topLeft = value;
1006
+ return this;
1007
+ }
1008
+ /**
1009
+ * Sets the top right corner value.
1010
+ *
1011
+ * @param value -
1012
+ * The value to set.
1013
+ *
1014
+ * @returns
1015
+ * This object.
1016
+ */ topRight(value) {
1017
+ this._corners.topRight = value;
1018
+ return this;
1019
+ }
1020
+ /**
1021
+ * Sets the bottom left and bottom right values.
1022
+ *
1023
+ * @param value -
1024
+ * The value for bottom left and bottom right.
1025
+ *
1026
+ * @returns
1027
+ * This object.
1028
+ */ bottom(value) {
1029
+ return this.bottomLeft(value).bottomRight(value);
1030
+ }
1031
+ /**
1032
+ * Sets the bottom left and top left values.
1033
+ *
1034
+ * @param value -
1035
+ * The value for bottom left and top left.
1036
+ *
1037
+ * @returns
1038
+ * This object.
1039
+ */ left(value) {
1040
+ return this.topLeft(value).bottomLeft(value);
1041
+ }
1042
+ /**
1043
+ * Sets the bottom right and top right values.
1044
+ *
1045
+ * @param value -
1046
+ * The value for bottom right and top right.
1047
+ *
1048
+ * @returns
1049
+ * This object.
1050
+ */ right(value) {
1051
+ return this.bottomRight(value).topRight(value);
1052
+ }
1053
+ /**
1054
+ * Sets the top left and top right values.
1055
+ *
1056
+ * @param value -
1057
+ * The value for top left and top right.
1058
+ *
1059
+ * @returns
1060
+ * This object.
1061
+ */ top(value) {
1062
+ return this.topLeft(value).topRight(value);
1063
+ }
1064
+ /**
1065
+ * Sets the corner values based on an object that
1066
+ * describes a set of quadrilateral corners.
1067
+ *
1068
+ * @param other -
1069
+ * The object that describes the corners.
1070
+ *
1071
+ * @returns
1072
+ * This object.
1073
+ */ from(other) {
1074
+ function isVerticals(candidate) {
1075
+ return candidate != null && (Object.prototype.hasOwnProperty.call(candidate, "bottom") || Object.prototype.hasOwnProperty.call(candidate, "top"));
1076
+ }
1077
+ function isHorizontals(candidate) {
1078
+ return candidate != null && (Object.prototype.hasOwnProperty.call(candidate, "left") || Object.prototype.hasOwnProperty.call(candidate, "right"));
1079
+ }
1080
+ function isCorners(candidate) {
1081
+ return candidate != null && (Object.prototype.hasOwnProperty.call(candidate, "bottomLeft") || Object.prototype.hasOwnProperty.call(candidate, "bottomRight") || Object.prototype.hasOwnProperty.call(candidate, "topLeft") || Object.prototype.hasOwnProperty.call(candidate, "topRight"));
1082
+ }
1083
+ const { bottomLeft, bottomRight, topLeft, topRight } = this._corners;
1084
+ if (isCorners(other)) {
1085
+ this._corners.bottomLeft = firstDefined(bottomLeft, other.bottomLeft);
1086
+ this._corners.bottomRight = firstDefined(bottomRight, other.bottomRight);
1087
+ this._corners.topLeft = firstDefined(topLeft, other.topLeft);
1088
+ this._corners.topRight = firstDefined(topRight, other.topRight);
1089
+ return this;
1090
+ }
1091
+ if (isVerticals(other)) {
1092
+ this._corners.bottomLeft = firstDefined(bottomLeft, other.bottom);
1093
+ this._corners.bottomRight = firstDefined(bottomRight, other.bottom);
1094
+ this._corners.topLeft = firstDefined(topLeft, other.top);
1095
+ this._corners.topRight = firstDefined(topRight, other.top);
1096
+ return this;
1097
+ }
1098
+ if (isHorizontals(other)) {
1099
+ this._corners.bottomLeft = firstDefined(bottomLeft, other.left);
1100
+ this._corners.bottomRight = firstDefined(bottomRight, other.right);
1101
+ this._corners.topLeft = firstDefined(topLeft, other.left);
1102
+ this._corners.topRight = firstDefined(topRight, other.right);
1103
+ return this;
1104
+ }
1105
+ if (!isEmptyObject(other)) {
1106
+ this._corners.bottomLeft = firstDefined(bottomLeft, other);
1107
+ this._corners.bottomRight = firstDefined(bottomRight, other);
1108
+ this._corners.topLeft = firstDefined(topLeft, other);
1109
+ this._corners.topRight = firstDefined(topRight, other);
1110
+ }
1111
+ return this;
1112
+ }
1113
+ /**
1114
+ * Copies another corners object into this builder.
1115
+ *
1116
+ * @param other -
1117
+ * The corners object to copy.
1118
+ *
1119
+ * @returns
1120
+ * This object.
1121
+ */ copy(other) {
1122
+ this._corners = structuredClone(other);
1123
+ return this;
1124
+ }
1125
+ /**
1126
+ * Builds the corners.
1127
+ *
1128
+ * @returns
1129
+ * The built corners.
1130
+ */ build() {
1131
+ return structuredClone(this._corners);
1132
+ }
1133
+ };
1134
+ //#endregion
1135
+ //#region src/geometry/rectangle.mts
1136
+ /**
1137
+ * Represents a helper object that can run calculations on a numeric quadrilateral.
1138
+ */ var ZRectangle = class ZRectangle {
1139
+ sides;
1140
+ /**
1141
+ * Initializes a new instance of this object.
1142
+ *
1143
+ * @param sides -
1144
+ * The numeric sides of a quadrilateral.
1145
+ */ constructor(sides) {
1146
+ this.sides = sides;
1147
+ }
1148
+ /**
1149
+ * Calculates the width of the rectangle.
1150
+ *
1151
+ * @returns
1152
+ * The numeric width of the rectangle.
1153
+ */ width() {
1154
+ const { left, right } = this.sides;
1155
+ return right - left;
1156
+ }
1157
+ /**
1158
+ * Calculates the height of the rectangle.
1159
+ *
1160
+ * @returns
1161
+ * The numeric height of the rectangle.
1162
+ */ height() {
1163
+ const { top, bottom } = this.sides;
1164
+ return bottom - top;
1165
+ }
1166
+ /**
1167
+ * Calculates the area of the rectangle.
1168
+ *
1169
+ * @returns
1170
+ * The numeric area of the rectangle.
1171
+ */ area() {
1172
+ return this.width() * this.height();
1173
+ }
1174
+ /**
1175
+ * Takes a candidate and attaches it to this rectangle that matches the anchor points.
1176
+ *
1177
+ * @param anchor -
1178
+ * The anchor point of this rectangle.
1179
+ * @param candidate -
1180
+ * The candidate rectangle to move
1181
+ * @param candidateAnchor -
1182
+ * The anchor point of the candidate rectangle.
1183
+ *
1184
+ * @returns
1185
+ * A new quadrilateral that has it's placement such that if candidate was moved
1186
+ * to this resulting position, would have its candidateAnchor be in the same
1187
+ * place as this rectangles specified anchor.
1188
+ */ attach(anchor, candidate, candidateAnchor) {
1189
+ const _candidate = new ZRectangle(candidate);
1190
+ const { x: ax, y: ay } = this.point(anchor);
1191
+ const { x: ox, y: oy } = new ZRectangle(candidate).point(candidateAnchor);
1192
+ const left = candidate.left + (ax - ox);
1193
+ const top = candidate.top + (ay - oy);
1194
+ const bottom = top + _candidate.height();
1195
+ const right = left + _candidate.width();
1196
+ return new ZQuadrilateralBuilder(0).left(left).right(right).top(top).bottom(bottom).build();
1197
+ }
1198
+ /**
1199
+ * Takes the candidate quadrilateral and adjusts it's coordinates to fit inside this rectangle.
1200
+ *
1201
+ * This is done by shifting the rectangle left, right, up, and down to make sure it is bounded
1202
+ * inside.
1203
+ *
1204
+ * If the candidate width or height is larger than this rectangle, thus it cannot fit, then
1205
+ * the candidate will be centered on the dimension where it is too big to fit.
1206
+ *
1207
+ * @param candidate -
1208
+ * The candidate quadrilateral to fit.
1209
+ *
1210
+ * @returns
1211
+ * A new quadrilateral that offsets candidate so that it can fit inside this
1212
+ * rectangle.
1213
+ */ offsetToFit(candidate) {
1214
+ let _candidate = candidate;
1215
+ const candidateRectangle = new ZRectangle(candidate);
1216
+ if (candidateRectangle.width() > this.width()) {
1217
+ const { x: cx } = candidateRectangle.middleCenter();
1218
+ const { x: tx } = this.middleCenter();
1219
+ _candidate = new ZQuadrilateralBuilder(0).copy(_candidate).left(_candidate.left - (cx - tx)).right(_candidate.right - (cx - tx)).build();
1220
+ } else {
1221
+ if (_candidate.left < this.sides.left) _candidate = new ZQuadrilateralBuilder(0).copy(_candidate).left(this.sides.left).right(_candidate.right + (this.sides.left - _candidate.left)).build();
1222
+ if (_candidate.right > this.sides.right) _candidate = new ZQuadrilateralBuilder(0).copy(_candidate).right(this.sides.right).left(_candidate.left - (_candidate.right - this.sides.right)).build();
1223
+ }
1224
+ if (candidateRectangle.height() > this.height()) {
1225
+ const { y: cy } = candidateRectangle.middleCenter();
1226
+ const { y: ty } = this.middleCenter();
1227
+ _candidate = new ZQuadrilateralBuilder(0).copy(_candidate).top(_candidate.top - (cy - ty)).bottom(_candidate.bottom - (cy - ty)).build();
1228
+ } else {
1229
+ if (_candidate.bottom > this.sides.bottom) _candidate = new ZQuadrilateralBuilder(0).copy(_candidate).bottom(this.sides.bottom).top(_candidate.top - (_candidate.bottom - this.sides.bottom)).build();
1230
+ if (_candidate.top < this.sides.top) _candidate = new ZQuadrilateralBuilder(0).copy(_candidate).top(this.sides.top).bottom(_candidate.bottom + (this.sides.top - _candidate.top)).build();
1231
+ }
1232
+ return _candidate;
1233
+ }
1234
+ /**
1235
+ * Calculates the (x, y) point given an anchor target.
1236
+ *
1237
+ * @param anchor -
1238
+ * The anchor target to calculate the point for.
1239
+ *
1240
+ * @returns
1241
+ * The numeric width of the rectangle.
1242
+ */ point(anchor) {
1243
+ const { bottom, left, right, top } = this.sides;
1244
+ const [vertical, horizontal] = anchor;
1245
+ const v = {
1246
+ [ZVerticalAnchor.Top]: top,
1247
+ [ZVerticalAnchor.Middle]: (bottom + top) / 2,
1248
+ [ZVerticalAnchor.Bottom]: bottom
1249
+ };
1250
+ return {
1251
+ x: {
1252
+ [ZHorizontalAnchor.Left]: left,
1253
+ [ZHorizontalAnchor.Center]: (right + left) / 2,
1254
+ [ZHorizontalAnchor.Right]: right
1255
+ }[horizontal],
1256
+ y: v[vertical]
1257
+ };
1258
+ }
1259
+ /**
1260
+ * Calculates the top left point of the rectangle.
1261
+ *
1262
+ * @returns
1263
+ * The top left point of the rectangle.
1264
+ */ topLeft = this.point.bind(this, [ZVerticalAnchor.Top, ZHorizontalAnchor.Left]);
1265
+ /**
1266
+ * Calculates the top center point of the rectangle.
1267
+ *
1268
+ * @returns
1269
+ * The top center point of the rectangle.
1270
+ */ topCenter = this.point.bind(this, [ZVerticalAnchor.Top, ZHorizontalAnchor.Center]);
1271
+ /**
1272
+ * Calculates the top right point of the rectangle.
1273
+ *
1274
+ * @returns
1275
+ * The top right point of the rectangle.
1276
+ */ topRight = this.point.bind(this, [ZVerticalAnchor.Top, ZHorizontalAnchor.Right]);
1277
+ /**
1278
+ * Calculates the middle left point of the rectangle.
1279
+ *
1280
+ * @returns
1281
+ * The middle left point of the rectangle.
1282
+ */ middleLeft = this.point.bind(this, [ZVerticalAnchor.Middle, ZHorizontalAnchor.Left]);
1283
+ /**
1284
+ * Calculates the middle center point of the rectangle.
1285
+ *
1286
+ * @returns
1287
+ * The middle center point of the rectangle.
1288
+ */ middleCenter = this.point.bind(this, [ZVerticalAnchor.Middle, ZHorizontalAnchor.Center]);
1289
+ /**
1290
+ * Calculates the middle right point of the rectangle.
1291
+ *
1292
+ * @returns
1293
+ * The middle right point of the rectangle.
1294
+ */ middleRight = this.point.bind(this, [ZVerticalAnchor.Middle, ZHorizontalAnchor.Right]);
1295
+ /**
1296
+ * Calculates the bottom left point of the rectangle.
1297
+ *
1298
+ * @returns
1299
+ * The bottom left point of the rectangle.
1300
+ */ bottomLeft = this.point.bind(this, [ZVerticalAnchor.Bottom, ZHorizontalAnchor.Left]);
1301
+ /**
1302
+ * Calculates the bottom center point of the rectangle.
1303
+ *
1304
+ * @returns
1305
+ * The bottom center point of the rectangle.
1306
+ */ bottomCenter = this.point.bind(this, [ZVerticalAnchor.Bottom, ZHorizontalAnchor.Center]);
1307
+ /**
1308
+ * Calculates the bottom right point of the rectangle.
1309
+ *
1310
+ * @returns
1311
+ * The bottom right point of the rectangle.
1312
+ */ bottomRight = this.point.bind(this, [ZVerticalAnchor.Bottom, ZHorizontalAnchor.Right]);
1313
+ };
1314
+ //#endregion
1315
+ //#region src/global/global.mts
1473
1316
  /* v8 ignore start -- @preserve */ /* istanbul ignore file -- @preserve */ /**
1474
- * Resolves the global object without referencing DOM globals so this can be
1475
- * consumed in Node builds that do not include the `dom` lib.
1476
- */ const $global = globalThis; /* v8 ignore end -- @preserve */
1477
-
1478
- /**
1479
- * A set of parameters that can be used for a string join.
1480
- *
1481
- * Join lists can be a regular object, null, undefined, or a tuple where the
1482
- * first item is the object to join, and the second item is a boolean that specifies
1483
- * whether to include it if the value is truthy.
1484
- *
1485
- * @param T -
1486
- * The type of data to join.
1487
- */ /**
1488
- * Similar to Array.join but filters out null and undefined items.
1489
- *
1490
- * @param delimiter -
1491
- * The delimiter that separates the items.
1492
- * @param items -
1493
- * The items to join.
1494
- * @param T -
1495
- * The type of data to join.
1496
- *
1497
- * @returns
1498
- * A string that joins the items that are defined, separated by delimiter.
1499
- *
1500
- * @example
1501
- *
1502
- * ```ts
1503
- * // 'a b d'
1504
- * const joinBySpace = joinDefined(' ', 'a', 'b', ['c', false], null, undefined, ['d', true]);
1505
- * // (Empty String)
1506
- * const joinEmpty = joinDefined('?');
1507
- * ```
1508
- */ function joinDefined(delimiter, ...items) {
1509
- return items.map((item)=>item instanceof Array ? item[1] ? item[0] : null : item).filter((item)=>item != null).join(delimiter);
1317
+ * Resolves the global object without referencing DOM globals so this can be
1318
+ * consumed in Node builds that do not include the `dom` lib.
1319
+ */ var $global = globalThis;
1320
+ //#endregion
1321
+ //#region src/join-defined/join-defined.mts
1322
+ /**
1323
+ * A set of parameters that can be used for a string join.
1324
+ *
1325
+ * Join lists can be a regular object, null, undefined, or a tuple where the
1326
+ * first item is the object to join, and the second item is a boolean that specifies
1327
+ * whether to include it if the value is truthy.
1328
+ *
1329
+ * @param T -
1330
+ * The type of data to join.
1331
+ */ /**
1332
+ * Similar to Array.join but filters out null and undefined items.
1333
+ *
1334
+ * @param delimiter -
1335
+ * The delimiter that separates the items.
1336
+ * @param items -
1337
+ * The items to join.
1338
+ * @param T -
1339
+ * The type of data to join.
1340
+ *
1341
+ * @returns
1342
+ * A string that joins the items that are defined, separated by delimiter.
1343
+ *
1344
+ * @example
1345
+ *
1346
+ * ```ts
1347
+ * // 'a b d'
1348
+ * const joinBySpace = joinDefined(' ', 'a', 'b', ['c', false], null, undefined, ['d', true]);
1349
+ * // (Empty String)
1350
+ * const joinEmpty = joinDefined('?');
1351
+ * ```
1352
+ */ function joinDefined(delimiter, ...items) {
1353
+ return items.map((item) => item instanceof Array ? item[1] ? item[0] : null : item).filter((item) => item != null).join(delimiter);
1510
1354
  }
1511
1355
  /**
1512
- * Alias to joinList with a space delimiter.
1513
- *
1514
- * @param items -
1515
- * The items to join.
1516
- *
1517
- * @returns
1518
- * A string that joins the items that are defined, separated by space delimiter.
1519
- *
1520
- * @see
1521
- * {@link joinDefined} for more information and examples.
1522
- */ const spaceJoinDefined = joinDefined.bind(null, " ");
1523
- /**
1524
- * Alias of spaceJoinList.
1525
- *
1526
- * @param items -
1527
- * The items to join.
1528
- *
1529
- * @returns
1530
- * A string that joins the items that are defined, separated by a space delimiter.
1531
- *
1532
- * @see
1533
- * {@link joinDefined} for more information and examples.
1534
- */ const cssJoinDefined = spaceJoinDefined;
1535
- /**
1536
- * Alias of joinList with a comma delimiter.
1537
- *
1538
- * @param items -
1539
- * The items to join.
1540
- *
1541
- * @returns
1542
- * A string that joins the items that are defined, separated by a comma delimiter.
1543
- *
1544
- * @see
1545
- * {@link joinDefined} for more information and examples.
1546
- */ const commaJoinDefined = joinDefined.bind(null, ",");
1547
- /**
1548
- * Alias of joinList with a semi-colon delimiter.
1549
- *
1550
- * @param items -
1551
- * The items to join.
1552
- *
1553
- * @returns
1554
- * A string that joins the items that are defined, separated by a semi-colon delimiter.
1555
- *
1556
- * @see
1557
- * {@link joinDefined} for more information and examples.
1558
- */ const semiColonJoinDefined = joinDefined.bind(null, ";");
1559
- /**
1560
- * Alias of joinList with a pipe delimiter.
1561
- *
1562
- * @param items -
1563
- * The items to join.
1564
- *
1565
- * @returns
1566
- * A string that joins the items that are defined, separated by a pipe delimiter.
1567
- *
1568
- * @see
1569
- * {@link joinDefined} for more information and examples.
1570
- */ const pipeJoinDefined = joinDefined.bind(null, "|");
1571
-
1572
- function _define_property$2(obj, key, value) {
1573
- if (key in obj) {
1574
- Object.defineProperty(obj, key, {
1575
- value: value,
1576
- enumerable: true,
1577
- configurable: true,
1578
- writable: true
1579
- });
1580
- } else {
1581
- obj[key] = value;
1582
- }
1583
- return obj;
1584
- }
1585
- class ZLazy {
1586
- initialized() {
1587
- return this._value != null;
1588
- }
1589
- async get() {
1590
- if (this._value == null) {
1591
- this._value = this._factory();
1592
- }
1593
- return this._value;
1594
- }
1595
- constructor(_factory){
1596
- _define_property$2(this, "_factory", void 0);
1597
- _define_property$2(this, "_value", void 0);
1598
- this._factory = _factory;
1599
- }
1600
- }
1601
-
1602
- /**
1603
- * A specific set of possible values that need to be checked for requirements.
1604
- *
1605
- * @param T -
1606
- * The type of value that is being checked.
1607
- */ /**
1608
- * Requires a value to be non null.
1609
- *
1610
- * @param val -
1611
- * The value to require. This can be a promise
1612
- * that can return null or undefined in addition to the
1613
- * value.
1614
- * @param T -
1615
- * The type of value that is being checked.
1616
- *
1617
- * @returns
1618
- * This method returns val if it is not null
1619
- * or undefined, otherwise, an error is thrown.
1620
- *
1621
- * @throws
1622
- * An error if the value is null or undefined.
1623
- */ async function required(val) {
1624
- if (val == null) {
1625
- throw new Error("A required value was not provided");
1626
- }
1627
- const _val = await val;
1628
- if (_val == null) {
1629
- throw new Error("A required value was not provided");
1630
- }
1631
- return _val;
1356
+ * Alias to joinList with a space delimiter.
1357
+ *
1358
+ * @param items -
1359
+ * The items to join.
1360
+ *
1361
+ * @returns
1362
+ * A string that joins the items that are defined, separated by space delimiter.
1363
+ *
1364
+ * @see
1365
+ * {@link joinDefined} for more information and examples.
1366
+ */ var spaceJoinDefined = joinDefined.bind(null, " ");
1367
+ /**
1368
+ * Alias of spaceJoinList.
1369
+ *
1370
+ * @param items -
1371
+ * The items to join.
1372
+ *
1373
+ * @returns
1374
+ * A string that joins the items that are defined, separated by a space delimiter.
1375
+ *
1376
+ * @see
1377
+ * {@link joinDefined} for more information and examples.
1378
+ */ var cssJoinDefined = spaceJoinDefined;
1379
+ /**
1380
+ * Alias of joinList with a comma delimiter.
1381
+ *
1382
+ * @param items -
1383
+ * The items to join.
1384
+ *
1385
+ * @returns
1386
+ * A string that joins the items that are defined, separated by a comma delimiter.
1387
+ *
1388
+ * @see
1389
+ * {@link joinDefined} for more information and examples.
1390
+ */ var commaJoinDefined = joinDefined.bind(null, ",");
1391
+ /**
1392
+ * Alias of joinList with a semi-colon delimiter.
1393
+ *
1394
+ * @param items -
1395
+ * The items to join.
1396
+ *
1397
+ * @returns
1398
+ * A string that joins the items that are defined, separated by a semi-colon delimiter.
1399
+ *
1400
+ * @see
1401
+ * {@link joinDefined} for more information and examples.
1402
+ */ var semiColonJoinDefined = joinDefined.bind(null, ";");
1403
+ /**
1404
+ * Alias of joinList with a pipe delimiter.
1405
+ *
1406
+ * @param items -
1407
+ * The items to join.
1408
+ *
1409
+ * @returns
1410
+ * A string that joins the items that are defined, separated by a pipe delimiter.
1411
+ *
1412
+ * @see
1413
+ * {@link joinDefined} for more information and examples.
1414
+ */ var pipeJoinDefined = joinDefined.bind(null, "|");
1415
+ //#endregion
1416
+ //#region src/lazy/lazy.mts
1417
+ var ZLazy = class {
1418
+ _factory;
1419
+ _value;
1420
+ constructor(_factory) {
1421
+ this._factory = _factory;
1422
+ }
1423
+ initialized() {
1424
+ return this._value != null;
1425
+ }
1426
+ async get() {
1427
+ if (this._value == null) this._value = this._factory();
1428
+ return this._value;
1429
+ }
1430
+ };
1431
+ //#endregion
1432
+ //#region src/obligation/obligation.mts
1433
+ /**
1434
+ * A specific set of possible values that need to be checked for requirements.
1435
+ *
1436
+ * @param T -
1437
+ * The type of value that is being checked.
1438
+ */ /**
1439
+ * Requires a value to be non null.
1440
+ *
1441
+ * @param val -
1442
+ * The value to require. This can be a promise
1443
+ * that can return null or undefined in addition to the
1444
+ * value.
1445
+ * @param T -
1446
+ * The type of value that is being checked.
1447
+ *
1448
+ * @returns
1449
+ * This method returns val if it is not null
1450
+ * or undefined, otherwise, an error is thrown.
1451
+ *
1452
+ * @throws
1453
+ * An error if the value is null or undefined.
1454
+ */ async function required(val) {
1455
+ if (val == null) throw new Error("A required value was not provided");
1456
+ const _val = await val;
1457
+ if (_val == null) throw new Error("A required value was not provided");
1458
+ return _val;
1632
1459
  }
1633
1460
  /**
1634
- * Allows a value to be null or undefined and has a fallback.
1635
- *
1636
- * @param val -
1637
- * The value to check. This can be a promise
1638
- * that can return null or undefined in addition to the
1639
- * value.
1640
- * @param fallback -
1641
- * The fallback value in the case that val is
1642
- * null or undefined.
1643
- * @param T -
1644
- * The type of value that is being checked.
1645
- *
1646
- * @returns
1647
- * This method returns val if it is not null
1648
- * or undefined, otherwise, the fallback is returned.
1649
- * If val is a promise and rejects, then fallback is
1650
- * also returned.
1651
- */ async function optional(val, fallback = null) {
1652
- if (val == null) {
1653
- return fallback;
1654
- }
1655
- try {
1656
- const _val = await val;
1657
- return _val == null ? fallback : _val;
1658
- } catch {
1659
- return fallback;
1660
- }
1461
+ * Allows a value to be null or undefined and has a fallback.
1462
+ *
1463
+ * @param val -
1464
+ * The value to check. This can be a promise
1465
+ * that can return null or undefined in addition to the
1466
+ * value.
1467
+ * @param fallback -
1468
+ * The fallback value in the case that val is
1469
+ * null or undefined.
1470
+ * @param T -
1471
+ * The type of value that is being checked.
1472
+ *
1473
+ * @returns
1474
+ * This method returns val if it is not null
1475
+ * or undefined, otherwise, the fallback is returned.
1476
+ * If val is a promise and rejects, then fallback is
1477
+ * also returned.
1478
+ */ async function optional(val, fallback = null) {
1479
+ if (val == null) return fallback;
1480
+ try {
1481
+ const _val = await val;
1482
+ return _val == null ? fallback : _val;
1483
+ } catch {
1484
+ return fallback;
1485
+ }
1661
1486
  }
1662
-
1663
- /**
1664
- * Represents a direction orientation.
1665
- */ var ZOrientation = /*#__PURE__*/ function(ZOrientation) {
1666
- /**
1667
- * Horizontal orientation.
1668
- *
1669
- * This type of orientation is a row
1670
- * style orientation or flex-row orientation.
1671
- */ ZOrientation["Horizontal"] = "horizontal";
1672
- /**
1673
- * Vertical orientation.
1674
- *
1675
- * This type of orientation is a column
1676
- * style orientation or block orientation.
1677
- */ ZOrientation["Vertical"] = "vertical";
1678
- return ZOrientation;
1487
+ //#endregion
1488
+ //#region src/orientation/orientation.mts
1489
+ /**
1490
+ * Represents a direction orientation.
1491
+ */ var ZOrientation = /* @__PURE__ */ function(ZOrientation) {
1492
+ /**
1493
+ * Horizontal orientation.
1494
+ *
1495
+ * This type of orientation is a row
1496
+ * style orientation or flex-row orientation.
1497
+ */ ZOrientation["Horizontal"] = "horizontal";
1498
+ /**
1499
+ * Vertical orientation.
1500
+ *
1501
+ * This type of orientation is a column
1502
+ * style orientation or block orientation.
1503
+ */ ZOrientation["Vertical"] = "vertical";
1504
+ return ZOrientation;
1679
1505
  }({});
1680
-
1681
- /**
1682
- * Peels a candidate string from the start of a string and splits it into two segments.
1683
- *
1684
- * @param str -
1685
- * The string to peel from.
1686
- * @param candidates -
1687
- * The candidate list of values to peel from str.
1688
- *
1689
- * @returns
1690
- * A tuple where the first item is the peeled string and
1691
- * the second item is the remainder of the string. If the string
1692
- * does not start with any given candidates, then the first
1693
- * item will be null and the second item will be str.
1694
- */ function peel(str, candidates) {
1695
- for (const check of candidates){
1696
- if (str.startsWith(check)) {
1697
- return [
1698
- str.substring(0, check.length),
1699
- str.substring(check.length)
1700
- ];
1701
- }
1702
- }
1703
- return [
1704
- null,
1705
- str
1706
- ];
1506
+ //#endregion
1507
+ //#region src/peel/peel.mts
1508
+ /**
1509
+ * Peels a candidate string from the start of a string and splits it into two segments.
1510
+ *
1511
+ * @param str -
1512
+ * The string to peel from.
1513
+ * @param candidates -
1514
+ * The candidate list of values to peel from str.
1515
+ *
1516
+ * @returns
1517
+ * A tuple where the first item is the peeled string and
1518
+ * the second item is the remainder of the string. If the string
1519
+ * does not start with any given candidates, then the first
1520
+ * item will be null and the second item will be str.
1521
+ */ function peel(str, candidates) {
1522
+ for (const check of candidates) if (str.startsWith(check)) return [str.substring(0, check.length), str.substring(check.length)];
1523
+ return [null, str];
1707
1524
  }
1708
1525
  /**
1709
- * Peels the values between an opening string set and a closing string set.
1710
- *
1711
- * The actual value will handle issues with internal opening and closing brackets
1712
- *
1713
- * @example
1714
- *
1715
- * ```ts
1716
- * const [peeled, rest] = peelBetween('[a, b, [c1, c2],[d]] other', '[' ']');
1717
- *
1718
- * // Outputs 'a, b, [c1, c2], [d]'
1719
- * console.log(peeled);
1720
- *
1721
- * // Outputs ' other' - white space is included'
1722
- * console.log(rest);
1723
- * ```
1724
- *
1725
- * @param str -
1726
- * The string to peel between.
1727
- * @param open -
1728
- * The opening string. This will test
1729
- * at the start of str.
1730
- * @param close -
1731
- * The closing string. This can be anywhere
1732
- * in the str. If this is equal to open, then
1733
- * the open string is removed from the start of the
1734
- * string and the rest of the string would be returned.
1735
- *
1736
- * @returns
1737
- * A tuple where the first argument is string that was found between
1738
- * the opening and closing bracket. Returns null if no string could
1739
- * be found between an open and close pair. The second argument will
1740
- * be the remaining text of the string, including whitespace.
1741
- */ function peelBetween(str, open, close) {
1742
- if (!str.startsWith(open)) {
1743
- return [
1744
- null,
1745
- str
1746
- ];
1747
- }
1748
- let stack = 1;
1749
- const _str = str.substring(open.length);
1750
- for(let i = 0; i < _str.length; ++i){
1751
- if (_str.startsWith(open, i)) {
1752
- stack += 1;
1753
- i += open.length - 1;
1754
- continue;
1755
- }
1756
- if (_str.startsWith(close, i)) {
1757
- stack -= 1;
1758
- if (stack === 0) {
1759
- return [
1760
- _str.substring(0, i),
1761
- _str.substring(i + close.length)
1762
- ];
1763
- }
1764
- i += close.length - 1;
1765
- }
1766
- }
1767
- return [
1768
- null,
1769
- str
1770
- ];
1526
+ * Peels the values between an opening string set and a closing string set.
1527
+ *
1528
+ * The actual value will handle issues with internal opening and closing brackets
1529
+ *
1530
+ * @example
1531
+ *
1532
+ * ```ts
1533
+ * const [peeled, rest] = peelBetween('[a, b, [c1, c2],[d]] other', '[' ']');
1534
+ *
1535
+ * // Outputs 'a, b, [c1, c2], [d]'
1536
+ * console.log(peeled);
1537
+ *
1538
+ * // Outputs ' other' - white space is included'
1539
+ * console.log(rest);
1540
+ * ```
1541
+ *
1542
+ * @param str -
1543
+ * The string to peel between.
1544
+ * @param open -
1545
+ * The opening string. This will test
1546
+ * at the start of str.
1547
+ * @param close -
1548
+ * The closing string. This can be anywhere
1549
+ * in the str. If this is equal to open, then
1550
+ * the open string is removed from the start of the
1551
+ * string and the rest of the string would be returned.
1552
+ *
1553
+ * @returns
1554
+ * A tuple where the first argument is string that was found between
1555
+ * the opening and closing bracket. Returns null if no string could
1556
+ * be found between an open and close pair. The second argument will
1557
+ * be the remaining text of the string, including whitespace.
1558
+ */ function peelBetween(str, open, close) {
1559
+ if (!str.startsWith(open)) return [null, str];
1560
+ let stack = 1;
1561
+ const _str = str.substring(open.length);
1562
+ for (let i = 0; i < _str.length; ++i) {
1563
+ if (_str.startsWith(open, i)) {
1564
+ stack += 1;
1565
+ i += open.length - 1;
1566
+ continue;
1567
+ }
1568
+ if (_str.startsWith(close, i)) {
1569
+ stack -= 1;
1570
+ if (stack === 0) return [_str.substring(0, i), _str.substring(i + close.length)];
1571
+ i += close.length - 1;
1572
+ }
1573
+ }
1574
+ return [null, str];
1771
1575
  }
1772
-
1773
- /**
1774
- * A function that reduces an object to keys and values that match a predicate.
1775
- *
1776
- * @param predicate -
1777
- * The predicate to match the key and value against.
1778
- * @param target -
1779
- * The object to reduce.
1780
- *
1781
- * @returns
1782
- * A reduced object that only contains key-value pairs that match
1783
- * the predicate.
1784
- */ function pickBy(predicate, target) {
1785
- const keys = Object.keys(target);
1786
- const reduced = {};
1787
- keys.forEach((key)=>{
1788
- const value = target[key];
1789
- if (predicate(key, value)) {
1790
- reduced[key] = value;
1791
- }
1792
- });
1793
- return reduced;
1576
+ //#endregion
1577
+ //#region src/pick/pick.mts
1578
+ /**
1579
+ * A function that reduces an object to keys and values that match a predicate.
1580
+ *
1581
+ * @param predicate -
1582
+ * The predicate to match the key and value against.
1583
+ * @param target -
1584
+ * The object to reduce.
1585
+ *
1586
+ * @returns
1587
+ * A reduced object that only contains key-value pairs that match
1588
+ * the predicate.
1589
+ */ function pickBy(predicate, target) {
1590
+ const keys = Object.keys(target);
1591
+ const reduced = {};
1592
+ keys.forEach((key) => {
1593
+ const value = target[key];
1594
+ if (predicate(key, value)) reduced[key] = value;
1595
+ });
1596
+ return reduced;
1794
1597
  }
1795
1598
  /**
1796
- * An alias to pickBy with a predicate of (_, v) =&gt; v != null.
1797
- *
1798
- * @param target -
1799
- * The target object to reduce.
1800
- *
1801
- * @returns
1802
- * The reduced object.
1803
- */ function pickDefined(target) {
1804
- return pickBy((_, v)=>v != null, target);
1599
+ * An alias to pickBy with a predicate of (_, v) =&gt; v != null.
1600
+ *
1601
+ * @param target -
1602
+ * The target object to reduce.
1603
+ *
1604
+ * @returns
1605
+ * The reduced object.
1606
+ */ function pickDefined(target) {
1607
+ return pickBy((_, v) => v != null, target);
1805
1608
  }
1806
1609
  /**
1807
- * An alias to pickBy((k) =&gt; k.startsWith('data-')).
1808
- *
1809
- * @param target -
1810
- * The target object to reduce.
1811
- *
1812
- * @returns
1813
- * The reduced object.
1814
- */ function pickDataAttributes(target) {
1815
- return pickBy((k)=>String(k).startsWith("data-"), target);
1610
+ * An alias to pickBy((k) =&gt; k.startsWith('data-')).
1611
+ *
1612
+ * @param target -
1613
+ * The target object to reduce.
1614
+ *
1615
+ * @returns
1616
+ * The reduced object.
1617
+ */ function pickDataAttributes(target) {
1618
+ return pickBy((k) => String(k).startsWith("data-"), target);
1816
1619
  }
1817
1620
  /**
1818
- * An alias to pickBy((k) =&gt; k.startsWith('on')).
1819
- *
1820
- * @param target -
1821
- * The target object to reduce.
1822
- *
1823
- * @returns
1824
- * The reduced object.
1825
- */ function pickEvents(target) {
1826
- return pickBy((k)=>String(k).startsWith("on"), target);
1621
+ * An alias to pickBy((k) =&gt; k.startsWith('on')).
1622
+ *
1623
+ * @param target -
1624
+ * The target object to reduce.
1625
+ *
1626
+ * @returns
1627
+ * The reduced object.
1628
+ */ function pickEvents(target) {
1629
+ return pickBy((k) => String(k).startsWith("on"), target);
1827
1630
  }
1828
-
1631
+ //#endregion
1632
+ //#region src/purge/purge.mts
1829
1633
  function purge(obj, property) {
1830
- if (obj[property] === undefined) {
1831
- delete obj[property];
1832
- }
1634
+ if (obj[property] === void 0) delete obj[property];
1833
1635
  }
1834
-
1835
- function _define_property$1(obj, key, value) {
1836
- if (key in obj) {
1837
- Object.defineProperty(obj, key, {
1838
- value: value,
1839
- enumerable: true,
1840
- configurable: true,
1841
- writable: true
1842
- });
1843
- } else {
1844
- obj[key] = value;
1845
- }
1846
- return obj;
1847
- }
1848
- /**
1849
- * A deserializer that deserializes a JSON string.
1850
- */ class ZDeserializeJson {
1851
- deserialize(candidate) {
1852
- const parsed = JSON.parse(candidate);
1853
- if (this._schema && !this._schema(parsed)) {
1854
- throw new Error("The parsed JSON does not conform to the given schema requirement");
1855
- }
1856
- return parsed;
1857
- }
1858
- constructor(_schema){
1859
- _define_property$1(this, "_schema", void 0);
1860
- this._schema = _schema;
1861
- }
1862
- }
1863
-
1864
- function _define_property(obj, key, value) {
1865
- if (key in obj) {
1866
- Object.defineProperty(obj, key, {
1867
- value: value,
1868
- enumerable: true,
1869
- configurable: true,
1870
- writable: true
1871
- });
1872
- } else {
1873
- obj[key] = value;
1874
- }
1875
- return obj;
1876
- }
1877
- /**
1878
- * A deserializer that attempts to deserialize multiple times through a series of supported languages.
1879
- *
1880
- * @param T -
1881
- * The type of data to deserialize.
1882
- * @param S -
1883
- * The input type
1884
- */ class ZDeserializeTry {
1885
- deserialize(candidate) {
1886
- const errors = [];
1887
- for (const child of this._children){
1888
- try {
1889
- return child.deserialize(candidate);
1890
- } catch (e) {
1891
- errors.push(e.message);
1892
- }
1893
- }
1894
- const msg = `Unable to deserialize candidate, ${candidate}.`;
1895
- errors.splice(0, 0, msg);
1896
- throw new Error(errors.join("\n\n"));
1897
- }
1898
- /**
1899
- * Initializes a new instance of this object.
1900
- *
1901
- * @param _children -
1902
- * The list of deserializer objects to try on a specific candidate.
1903
- * The first deserializer to succeed will return the target object.
1904
- * If no deserializer is able to deserialize the candidate, then an
1905
- * error is throw with a mapping of serialization errors between each
1906
- * deserializer.
1907
- */ constructor(_children){
1908
- _define_property(this, "_children", void 0);
1909
- this._children = _children;
1910
- }
1911
- }
1912
-
1913
- /**
1914
- * Represents a serializer that serializes anything to a JSON string.
1915
- */ class ZSerializeJson {
1916
- serialize(candidate) {
1917
- return JSON.stringify(candidate, undefined, 2);
1918
- }
1919
- }
1920
-
1921
- /**
1922
- * Represents a setter function for when you want to set a single value,
1923
- * but you have an array instead.
1924
- *
1925
- * This is useful when you want to support lists of items, but you need
1926
- * backwards compatibility for setting a single item. This is primarily meant
1927
- * to be use with bind to construct a new method setter that takes an array
1928
- * and forwards it to a setter method which will accept a single value of the
1929
- * first item in the target value.
1930
- *
1931
- * @param setValue -
1932
- * The setter function that takes a single value. This will receive
1933
- * the first item of the value list.
1934
- * @param fallback -
1935
- * The fallback value in the case that there are no values.
1936
- * @param value -
1937
- * The value list to retrieve the first item from.
1938
- * @param T -
1939
- * The type of data that the array holds.
1940
- *
1941
- * @example
1942
- *
1943
- * ```ts
1944
- * // An example of a react component that needs a value of an array, but you only care about a single selection.
1945
- * const [value, setValue] = useState<TypesOfPie>();
1946
- * const _values = useMemo(() => value ? [value] : [], [value]);
1947
- * const _setValues = setFirst.bind(null, setValue, undefined);
1948
- *
1949
- * return <ComponentWithMultiSelectSupport values={_values} onValuesChange={_setValues} />
1950
- * ```
1951
- */ function setFirst(setValue, fallback, value) {
1952
- const _value = value?.length ? value[0] : fallback;
1953
- setValue(_value);
1636
+ //#endregion
1637
+ //#region src/serialize/deserialize-json.mts
1638
+ /**
1639
+ * A deserializer that deserializes a JSON string.
1640
+ */ var ZDeserializeJson = class {
1641
+ _schema;
1642
+ constructor(_schema) {
1643
+ this._schema = _schema;
1644
+ }
1645
+ deserialize(candidate) {
1646
+ const parsed = JSON.parse(candidate);
1647
+ if (this._schema && !this._schema(parsed)) throw new Error("The parsed JSON does not conform to the given schema requirement");
1648
+ return parsed;
1649
+ }
1650
+ };
1651
+ //#endregion
1652
+ //#region src/serialize/deserialize-try.mts
1653
+ /**
1654
+ * A deserializer that attempts to deserialize multiple times through a series of supported languages.
1655
+ *
1656
+ * @param T -
1657
+ * The type of data to deserialize.
1658
+ * @param S -
1659
+ * The input type
1660
+ */ var ZDeserializeTry = class {
1661
+ _children;
1662
+ /**
1663
+ * Initializes a new instance of this object.
1664
+ *
1665
+ * @param _children -
1666
+ * The list of deserializer objects to try on a specific candidate.
1667
+ * The first deserializer to succeed will return the target object.
1668
+ * If no deserializer is able to deserialize the candidate, then an
1669
+ * error is throw with a mapping of serialization errors between each
1670
+ * deserializer.
1671
+ */ constructor(_children) {
1672
+ this._children = _children;
1673
+ }
1674
+ deserialize(candidate) {
1675
+ const errors = [];
1676
+ for (const child of this._children) try {
1677
+ return child.deserialize(candidate);
1678
+ } catch (e) {
1679
+ errors.push(e.message);
1680
+ }
1681
+ const msg = `Unable to deserialize candidate, ${JSON.stringify(candidate)}.`;
1682
+ errors.splice(0, 0, msg);
1683
+ throw new Error(errors.join("\n\n"));
1684
+ }
1685
+ };
1686
+ //#endregion
1687
+ //#region src/serialize/serialize-json.mts
1688
+ /**
1689
+ * Represents a serializer that serializes anything to a JSON string.
1690
+ */ var ZSerializeJson = class {
1691
+ serialize(candidate) {
1692
+ return JSON.stringify(candidate, void 0, 2);
1693
+ }
1694
+ };
1695
+ //#endregion
1696
+ //#region src/set-first/set-first.mts
1697
+ /**
1698
+ * Represents a setter function for when you want to set a single value,
1699
+ * but you have an array instead.
1700
+ *
1701
+ * This is useful when you want to support lists of items, but you need
1702
+ * backwards compatibility for setting a single item. This is primarily meant
1703
+ * to be use with bind to construct a new method setter that takes an array
1704
+ * and forwards it to a setter method which will accept a single value of the
1705
+ * first item in the target value.
1706
+ *
1707
+ * @param setValue -
1708
+ * The setter function that takes a single value. This will receive
1709
+ * the first item of the value list.
1710
+ * @param fallback -
1711
+ * The fallback value in the case that there are no values.
1712
+ * @param value -
1713
+ * The value list to retrieve the first item from.
1714
+ * @param T -
1715
+ * The type of data that the array holds.
1716
+ *
1717
+ * @example
1718
+ *
1719
+ * ```ts
1720
+ * // An example of a react component that needs a value of an array, but you only care about a single selection.
1721
+ * const [value, setValue] = useState<TypesOfPie>();
1722
+ * const _values = useMemo(() => value ? [value] : [], [value]);
1723
+ * const _setValues = setFirst.bind(null, setValue, undefined);
1724
+ *
1725
+ * return <ComponentWithMultiSelectSupport values={_values} onValuesChange={_setValues} />
1726
+ * ```
1727
+ */ function setFirst(setValue, fallback, value) {
1728
+ setValue(value?.length ? value[0] : fallback);
1954
1729
  }
1955
-
1956
- /**
1957
- * Halts the current thread to invoke an event loop.
1958
- *
1959
- * @param ms -
1960
- * The total number of milliseconds to sleep.
1961
- *
1962
- * @returns
1963
- * A promise that resolves after ms milliseconds.
1964
- */ /**
1965
- * Halts the current thread to invoke an event loop.
1966
- *
1967
- * @param ms -
1968
- * The total number of milliseconds to sleep.
1969
- * @param T -
1970
- * The type of value that will be resolved.
1971
- *
1972
- * @returns
1973
- * A promise that resolves with val after ms milliseconds.
1974
- */ function sleep(ms = 0, val = undefined) {
1975
- return new Promise((resolve)=>setTimeout(()=>resolve(val), ms));
1730
+ //#endregion
1731
+ //#region src/sleep/sleep.mts
1732
+ /**
1733
+ * Halts the current thread to invoke an event loop.
1734
+ *
1735
+ * @param ms -
1736
+ * The total number of milliseconds to sleep.
1737
+ *
1738
+ * @returns
1739
+ * A promise that resolves after ms milliseconds.
1740
+ */ /**
1741
+ * Halts the current thread to invoke an event loop.
1742
+ *
1743
+ * @param ms -
1744
+ * The total number of milliseconds to sleep.
1745
+ * @param T -
1746
+ * The type of value that will be resolved.
1747
+ *
1748
+ * @returns
1749
+ * A promise that resolves with val after ms milliseconds.
1750
+ */ function sleep(ms = 0, val = void 0) {
1751
+ return new Promise((resolve) => setTimeout(() => resolve(val), ms));
1976
1752
  }
1977
-
1978
- /**
1979
- * This is just a method that allows you to tag an interpolation
1980
- * string as a syntax language.
1981
- *
1982
- * This is useful with IDE extensions that can detect the language
1983
- * and do the syntax highlighting for you.
1984
- *
1985
- * @param strings -
1986
- * The string breaks for interpolation.
1987
- * @param expressions -
1988
- * The equivalent expressions that break apart
1989
- * the single string literal.
1990
- *
1991
- * @returns
1992
- * The compiled string literal. This is no different
1993
- * than letting native JavaScript do it for you.
1994
- *
1995
- * @example
1996
- *
1997
- * ```ts
1998
- * const html = tag;
1999
- * const css = tag;
2000
- *
2001
- * const $html = html`
2002
- * <div>Some IDE extensions will highlight this as html</div>
2003
- * `
2004
- *
2005
- * const $css = css`
2006
- * button {
2007
- * display: grid;
2008
- * }
2009
- * `
2010
- * ```
2011
- */ function tag(strings, ...expressions) {
2012
- let [result] = strings;
2013
- for(let i = 1, l = strings.length; i < l; i++){
2014
- result += expressions[i - 1];
2015
- result += strings[i];
2016
- }
2017
- return result;
1753
+ //#endregion
1754
+ //#region src/tag/tag.mts
1755
+ /**
1756
+ * This is just a method that allows you to tag an interpolation
1757
+ * string as a syntax language.
1758
+ *
1759
+ * This is useful with IDE extensions that can detect the language
1760
+ * and do the syntax highlighting for you.
1761
+ *
1762
+ * @param strings -
1763
+ * The string breaks for interpolation.
1764
+ * @param expressions -
1765
+ * The equivalent expressions that break apart
1766
+ * the single string literal.
1767
+ *
1768
+ * @returns
1769
+ * The compiled string literal. This is no different
1770
+ * than letting native JavaScript do it for you.
1771
+ *
1772
+ * @example
1773
+ *
1774
+ * ```ts
1775
+ * const html = tag;
1776
+ * const css = tag;
1777
+ *
1778
+ * const $html = html`
1779
+ * <div>Some IDE extensions will highlight this as html</div>
1780
+ * `
1781
+ *
1782
+ * const $css = css`
1783
+ * button {
1784
+ * display: grid;
1785
+ * }
1786
+ * `
1787
+ * ```
1788
+ */ function tag(strings, ...expressions) {
1789
+ let [result] = strings;
1790
+ for (let i = 1, l = strings.length; i < l; i++) {
1791
+ result += String(expressions[i - 1]);
1792
+ result += strings[i];
1793
+ }
1794
+ return result;
2018
1795
  }
2019
1796
  /**
2020
- * An alias for {@link tag}.
2021
- *
2022
- * Some {@link https://marketplace.visualstudio.com/items?itemName=Tobermory.es6-string-html | IDE extensions will detect the string}
2023
- * interpolation as html when using this tag.
2024
- */ const html = tag;
2025
- /**
2026
- * An alias for {@link tag}.
2027
- *
2028
- * Some {@link https://marketplace.visualstudio.com/items?itemName=bashmish.es6-string-css | IDE extensions will detect the string}
2029
- * interpolation as css when using this tag.
2030
- */ const css = tag;
2031
- /**
2032
- * An alias for {@link tag}.
2033
- *
2034
- * Some {@link https://marketplace.visualstudio.com/items?itemName=zjcompt.es6-string-javascript | IDE extensions will detect the string}
2035
- * interpolation as javascript when using this tag.
2036
- */ const js = tag;
2037
- /**
2038
- * See {@link js}
2039
- */ const javascript = tag;
2040
- /**
2041
- * An alias for {@link tag}.
2042
- *
2043
- * Some {@link https://marketplace.visualstudio.com/items?itemName=jeoht.es6-string-markdown | IDE extensions will detect the string}
2044
- * interpolation as markdown when using this tag.
2045
- */ const md = tag;
2046
- /**
2047
- * See {@link md}
2048
- */ const markdown = tag;
2049
- /**
2050
- * An alias for {@link tag}.
2051
- *
2052
- * Some {@link https://marketplace.visualstudio.com/items?itemName=HoodieCollin.es6-string-typescript | IDE extensions will detect the string}
2053
- * interpolation as typescript when using this tag.
2054
- */ const ts = tag;
2055
- /**
2056
- * See {@link ts}
2057
- */ const typescript = tag;
2058
- /**
2059
- * An alias for {@link tag}.
2060
- */ const sh = tag;
2061
- /**
2062
- * An alias for {@link tag}.
2063
- */ const bash = tag;
2064
- /**
2065
- * An alias for {@link tag}.
2066
- */ const zsh = tag;
2067
-
2068
- /**
2069
- * Invokes the candidate function and returns undefined if an error is thrown from it.
2070
- *
2071
- * @param candidate -
2072
- * The candidate function to run.
2073
- *
2074
- * @returns
2075
- * The result from candidate. Returns undefined if candidate throws an Error.
2076
- */ /**
2077
- * Invokes the candidate function and returns fallback if an error is thrown from it.
2078
- *
2079
- * @param candidate -
2080
- * The candidate function to run.
2081
- * @param fallback -
2082
- * The fallback value to return if candidate throws an error.
2083
- *
2084
- * @returns
2085
- * The result from candidate. Returns fallback if candidate throws an Error.
2086
- * If no fallback value is provided, then undefined is returned.
2087
- */ function tryFallback(candidate, fallback) {
2088
- try {
2089
- return candidate();
2090
- } catch {
2091
- return fallback;
2092
- }
1797
+ * An alias for {@link tag}.
1798
+ *
1799
+ * Some {@link https://marketplace.visualstudio.com/items?itemName=Tobermory.es6-string-html | IDE extensions will detect the string}
1800
+ * interpolation as html when using this tag.
1801
+ */ var html = tag;
1802
+ /**
1803
+ * An alias for {@link tag}.
1804
+ *
1805
+ * Some {@link https://marketplace.visualstudio.com/items?itemName=bashmish.es6-string-css | IDE extensions will detect the string}
1806
+ * interpolation as css when using this tag.
1807
+ */ var css = tag;
1808
+ /**
1809
+ * An alias for {@link tag}.
1810
+ *
1811
+ * Some {@link https://marketplace.visualstudio.com/items?itemName=zjcompt.es6-string-javascript | IDE extensions will detect the string}
1812
+ * interpolation as javascript when using this tag.
1813
+ */ var js = tag;
1814
+ /**
1815
+ * See {@link js}
1816
+ */ var javascript = tag;
1817
+ /**
1818
+ * An alias for {@link tag}.
1819
+ *
1820
+ * Some {@link https://marketplace.visualstudio.com/items?itemName=jeoht.es6-string-markdown | IDE extensions will detect the string}
1821
+ * interpolation as markdown when using this tag.
1822
+ */ var md = tag;
1823
+ /**
1824
+ * See {@link md}
1825
+ */ var markdown = tag;
1826
+ /**
1827
+ * An alias for {@link tag}.
1828
+ *
1829
+ * Some {@link https://marketplace.visualstudio.com/items?itemName=HoodieCollin.es6-string-typescript | IDE extensions will detect the string}
1830
+ * interpolation as typescript when using this tag.
1831
+ */ var ts = tag;
1832
+ /**
1833
+ * See {@link ts}
1834
+ */ var typescript = tag;
1835
+ /**
1836
+ * An alias for {@link tag}.
1837
+ */ var sh = tag;
1838
+ /**
1839
+ * An alias for {@link tag}.
1840
+ */ var bash = tag;
1841
+ /**
1842
+ * An alias for {@link tag}.
1843
+ */ var zsh = tag;
1844
+ //#endregion
1845
+ //#region src/try/try-fallback.mts
1846
+ /**
1847
+ * Invokes the candidate function and returns undefined if an error is thrown from it.
1848
+ *
1849
+ * @param candidate -
1850
+ * The candidate function to run.
1851
+ *
1852
+ * @returns
1853
+ * The result from candidate. Returns undefined if candidate throws an Error.
1854
+ */ /**
1855
+ * Invokes the candidate function and returns fallback if an error is thrown from it.
1856
+ *
1857
+ * @param candidate -
1858
+ * The candidate function to run.
1859
+ * @param fallback -
1860
+ * The fallback value to return if candidate throws an error.
1861
+ *
1862
+ * @returns
1863
+ * The result from candidate. Returns fallback if candidate throws an Error.
1864
+ * If no fallback value is provided, then undefined is returned.
1865
+ */ function tryFallback(candidate, fallback) {
1866
+ try {
1867
+ return candidate();
1868
+ } catch {
1869
+ return fallback;
1870
+ }
2093
1871
  }
2094
1872
  /**
2095
- * Invokes the candidate function and returns undefined if an rejected promise is returned from it.
2096
- *
2097
- * @param candidate -
2098
- * The candidate function to run.
2099
- * @param fallback -
2100
- * The optional fallback value to return if the candidate throws an Error.
2101
- *
2102
- * @returns
2103
- * A promise that resolves with the result from candidate or fallback
2104
- * if candidate returns a rejected promise. Resolves with undefined
2105
- * if no fallback is provided.
2106
- */ async function tryFallbackAsync(candidate, fallback) {
2107
- try {
2108
- return await candidate();
2109
- } catch {
2110
- return fallback;
2111
- }
1873
+ * Invokes the candidate function and returns undefined if an rejected promise is returned from it.
1874
+ *
1875
+ * @param candidate -
1876
+ * The candidate function to run.
1877
+ * @param fallback -
1878
+ * The optional fallback value to return if the candidate throws an Error.
1879
+ *
1880
+ * @returns
1881
+ * A promise that resolves with the result from candidate or fallback
1882
+ * if candidate returns a rejected promise. Resolves with undefined
1883
+ * if no fallback is provided.
1884
+ */ async function tryFallbackAsync(candidate, fallback) {
1885
+ try {
1886
+ return await candidate();
1887
+ } catch {
1888
+ return fallback;
1889
+ }
2112
1890
  }
2113
-
2114
- /**
2115
- * Attempts to parse the string buffer as json.
2116
- *
2117
- * This is similar to JSON.parse, but instead of throwing
2118
- * an error, it returns the fallback.
2119
- *
2120
- * @param buffer -
2121
- * The string buffer that may be json.
2122
- * @param fallback -
2123
- * The fallback value in the case that buffer
2124
- * cannot be parsed. Note that parsing the text
2125
- * "null" will return null instead of the fallback.
2126
- * The default value for this is null.
2127
- *
2128
- * @returns
2129
- * The parsed value of the buffer when parsed as JSON. If
2130
- * buffer is null, undefined, or does not represent valid
2131
- * JSON, then the fallback is returned.
2132
- */ function tryJsonParse(buffer, fallback = null) {
2133
- if (buffer == null) {
2134
- return fallback;
2135
- }
2136
- // This is not really necessary because it is handled in the
2137
- // JSON.parse method, but this avoids parsing random binary data.
2138
- // If someone tries to read a buffer that's 300MB, there's no point
2139
- // trying to parse it if it's just random binary data. This can
2140
- // still happen if the first binary character is { or [, but
2141
- // most situations won't have this happen.
2142
- const [firstChar] = buffer;
2143
- if (firstChar !== "{" && firstChar !== "[") {
2144
- return fallback;
2145
- }
2146
- return tryFallback(()=>JSON.parse(buffer), fallback);
1891
+ //#endregion
1892
+ //#region src/try/try-json-parse.mts
1893
+ /**
1894
+ * Attempts to parse the string buffer as json.
1895
+ *
1896
+ * This is similar to JSON.parse, but instead of throwing
1897
+ * an error, it returns the fallback.
1898
+ *
1899
+ * @param buffer -
1900
+ * The string buffer that may be json.
1901
+ * @param fallback -
1902
+ * The fallback value in the case that buffer
1903
+ * cannot be parsed. Note that parsing the text
1904
+ * "null" will return null instead of the fallback.
1905
+ * The default value for this is null.
1906
+ *
1907
+ * @returns
1908
+ * The parsed value of the buffer when parsed as JSON. If
1909
+ * buffer is null, undefined, or does not represent valid
1910
+ * JSON, then the fallback is returned.
1911
+ */ function tryJsonParse(buffer, fallback = null) {
1912
+ if (buffer == null) return fallback;
1913
+ const [firstChar] = buffer;
1914
+ if (firstChar !== "{" && firstChar !== "[") return fallback;
1915
+ return tryFallback(() => JSON.parse(buffer), fallback);
2147
1916
  }
2148
-
1917
+ //#endregion
2149
1918
  exports.$global = $global;
2150
1919
  exports.ZAssert = ZAssert;
2151
1920
  exports.ZDateFormats = ZDateFormats;
@@ -2221,4 +1990,5 @@ exports.ts = ts;
2221
1990
  exports.typescript = typescript;
2222
1991
  exports.userTimeZone = userTimeZone;
2223
1992
  exports.zsh = zsh;
2224
- //# sourceMappingURL=index.cjs.map
1993
+
1994
+ //# sourceMappingURL=index.cjs.map