@oscarpalmer/abydon 0.15.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/dist/abydon.full.mjs +1443 -0
  2. package/dist/constants.d.mts +20 -0
  3. package/dist/constants.mjs +27 -0
  4. package/dist/fragment-9qTBAvtR.d.mts +82 -0
  5. package/dist/fragment.d.mts +2 -0
  6. package/dist/{fragment.js → fragment.mjs} +41 -14
  7. package/dist/fragments.d.mts +16 -0
  8. package/dist/{fragments.js → fragments.mjs} +10 -4
  9. package/dist/helpers/dom.d.mts +6 -0
  10. package/dist/helpers/{dom.js → dom.mjs} +4 -12
  11. package/dist/helpers/index.d.mts +9 -0
  12. package/dist/helpers/index.mjs +23 -0
  13. package/dist/index.d.mts +21 -0
  14. package/dist/index.mjs +24 -0
  15. package/dist/models.d.mts +2 -0
  16. package/dist/models.mjs +1 -0
  17. package/dist/node/attribute/index.d.mts +6 -0
  18. package/dist/node/attribute/index.mjs +41 -0
  19. package/dist/node/attribute/value.d.mts +6 -0
  20. package/dist/node/attribute/value.mjs +65 -0
  21. package/dist/node/event.d.mts +4 -0
  22. package/dist/node/event.mjs +25 -0
  23. package/dist/node/index.d.mts +6 -0
  24. package/dist/node/{index.js → index.mjs} +10 -8
  25. package/dist/node/value.d.mts +7 -0
  26. package/dist/node/{value.js → value.mjs} +12 -10
  27. package/dist/parse.d.mts +6 -0
  28. package/dist/{parse.js → parse.mjs} +11 -1
  29. package/package.json +42 -42
  30. package/src/constants.ts +30 -10
  31. package/src/fragment.ts +12 -24
  32. package/src/fragments.ts +3 -5
  33. package/src/helpers/dom.ts +1 -20
  34. package/src/helpers/index.ts +18 -15
  35. package/src/index.ts +14 -10
  36. package/src/models.ts +10 -1
  37. package/src/node/attribute/index.ts +22 -21
  38. package/src/node/attribute/value.ts +47 -37
  39. package/src/node/event.ts +26 -33
  40. package/src/node/index.ts +6 -18
  41. package/src/node/value.ts +15 -46
  42. package/src/parse.ts +15 -17
  43. package/dist/abydon.full.js +0 -1274
  44. package/dist/constants.js +0 -10
  45. package/dist/helpers/index.js +0 -14
  46. package/dist/index.js +0 -11
  47. package/dist/models.js +0 -0
  48. package/dist/node/attribute/index.js +0 -39
  49. package/dist/node/attribute/value.js +0 -56
  50. package/dist/node/event.js +0 -30
  51. package/types/constants.d.ts +0 -9
  52. package/types/fragment.d.ts +0 -38
  53. package/types/fragments.d.ts +0 -13
  54. package/types/helpers/dom.d.ts +0 -3
  55. package/types/helpers/index.d.ts +0 -5
  56. package/types/index.d.ts +0 -9
  57. package/types/models.d.ts +0 -32
  58. package/types/node/attribute/index.d.ts +0 -3
  59. package/types/node/attribute/value.d.ts +0 -3
  60. package/types/node/event.d.ts +0 -3
  61. package/types/node/index.d.ts +0 -2
  62. package/types/node/value.d.ts +0 -3
  63. package/types/parse.d.ts +0 -2
@@ -0,0 +1,1443 @@
1
+ //#region node_modules/@oscarpalmer/mora/dist/constants.js
2
+ const ACTIVE = {};
3
+ const BATCH = {
4
+ depth: 0,
5
+ handlers: /* @__PURE__ */ new Set()
6
+ };
7
+ const METHODS_AFFECTING_LENGTH = new Set([
8
+ "pop",
9
+ "push",
10
+ "shift",
11
+ "unshift"
12
+ ]);
13
+ const METHODS_UPDATE = new Set([
14
+ ...METHODS_AFFECTING_LENGTH,
15
+ "copyWithin",
16
+ "fill",
17
+ "reverse",
18
+ "sort",
19
+ "splice"
20
+ ]);
21
+ const NAME_ARRAY = "array";
22
+ const NAME_COMPUTED = "computed";
23
+ const NAME_EFFECT = "effect";
24
+ const NAME_MORA = "$mora";
25
+ const NAME_SIGNAL = "signal";
26
+ const NAME_STORE = "store";
27
+ const NAME_ALL = new Set([
28
+ NAME_ARRAY,
29
+ NAME_COMPUTED,
30
+ NAME_SIGNAL,
31
+ NAME_STORE
32
+ ]);
33
+ //#endregion
34
+ //#region node_modules/@oscarpalmer/mora/dist/effect.js
35
+ var Effect = class {
36
+ constructor(callback) {
37
+ Object.defineProperty(this, NAME_MORA, { value: NAME_EFFECT });
38
+ this.state = { callback };
39
+ runEffect(this);
40
+ }
41
+ };
42
+ function runEffect(effect$1) {
43
+ const previousEffect = ACTIVE.effect;
44
+ ACTIVE.effect = effect$1;
45
+ try {
46
+ effect$1.state.callback();
47
+ } finally {
48
+ ACTIVE.effect = previousEffect;
49
+ }
50
+ }
51
+ function effect(callback) {
52
+ return typeof callback === "function" ? new Effect(callback) : void 0;
53
+ }
54
+ //#endregion
55
+ //#region node_modules/@oscarpalmer/mora/dist/helpers/is.js
56
+ function isArray(value) {
57
+ return isMora(value, NAME_ARRAY);
58
+ }
59
+ function isComputed(value) {
60
+ return isMora(value, NAME_COMPUTED);
61
+ }
62
+ function isEffect(value) {
63
+ return isMora(value, NAME_EFFECT);
64
+ }
65
+ function isMora(value, name) {
66
+ return typeof value === "object" && value != null && "$mora" in value && (typeof name === "string" ? value["$mora"] === name : name.has(value["$mora"]));
67
+ }
68
+ function isReactive(value) {
69
+ return isMora(value, NAME_ALL);
70
+ }
71
+ function isSignal(value) {
72
+ return isMora(value, NAME_SIGNAL);
73
+ }
74
+ //#endregion
75
+ //#region node_modules/@oscarpalmer/mora/dist/batch.js
76
+ function flushHandlers() {
77
+ while (BATCH.depth === 0 && BATCH.handlers.size > 0) {
78
+ const handlers = [...BATCH.handlers];
79
+ BATCH.handlers.clear();
80
+ for (const handler of handlers) if (isEffect(handler)) runEffect(handler);
81
+ else handler.callback(handler.state.value);
82
+ }
83
+ }
84
+ function startBatch() {
85
+ BATCH.depth += 1;
86
+ }
87
+ function stopBatch() {
88
+ if (BATCH.depth > 0) BATCH.depth -= 1;
89
+ flushHandlers();
90
+ }
91
+ //#endregion
92
+ //#region node_modules/@oscarpalmer/mora/dist/subscription.js
93
+ var Subscription = class {
94
+ callback;
95
+ state;
96
+ constructor(state, callback) {
97
+ this.state = state;
98
+ this.callback = callback;
99
+ callback(state.value);
100
+ }
101
+ destroy() {
102
+ this.callback = noop$1;
103
+ this.state = void 0;
104
+ }
105
+ };
106
+ function noop$1() {}
107
+ function subscribe(state, callback) {
108
+ if (typeof callback !== "function" || state.subscriptions.has(callback)) return noop$1;
109
+ state.subscriptions.set(callback, new Subscription(state, callback));
110
+ return () => {
111
+ unsubscribe(state, callback);
112
+ };
113
+ }
114
+ function unsubscribe(state, callback) {
115
+ state.subscriptions.get(callback)?.destroy();
116
+ state.subscriptions.delete(callback);
117
+ }
118
+ //#endregion
119
+ //#region node_modules/@oscarpalmer/mora/dist/value/reactive.js
120
+ var Reactive = class {
121
+ state = {
122
+ computeds: /* @__PURE__ */ new Set(),
123
+ effects: /* @__PURE__ */ new Set(),
124
+ equal: Object.is,
125
+ subscriptions: /* @__PURE__ */ new Map(),
126
+ value: void 0
127
+ };
128
+ constructor(name, value, options) {
129
+ this.state.value = value;
130
+ if (typeof options === "object" && typeof options.equal === "function") this.state.equal = options.equal;
131
+ Object.defineProperty(this, NAME_MORA, { value: name });
132
+ }
133
+ peek() {
134
+ return this.state.value;
135
+ }
136
+ subscribe(callback) {
137
+ return subscribe(this.state, callback);
138
+ }
139
+ toJSON() {
140
+ return this.get();
141
+ }
142
+ toString() {
143
+ return String(this.get());
144
+ }
145
+ unsubscribe(callback) {
146
+ unsubscribe(this.state, callback);
147
+ }
148
+ };
149
+ //#endregion
150
+ //#region node_modules/@oscarpalmer/mora/dist/value/computed.js
151
+ var Computed = class extends Reactive {
152
+ effect = {
153
+ dirty: true,
154
+ instance: void 0
155
+ };
156
+ constructor(callback, options) {
157
+ super(NAME_COMPUTED, void 0, options);
158
+ this.effect.instance = effect(() => {
159
+ if (!this.effect.dirty) return;
160
+ const previousComputed = ACTIVE.computed;
161
+ ACTIVE.computed = this;
162
+ const value = callback();
163
+ ACTIVE.computed = previousComputed;
164
+ if (!this.state.equal(this.state.value, value)) {
165
+ this.state.value = value;
166
+ for (const computed$1 of this.state.computeds) computed$1.effect.dirty = true;
167
+ for (const effect$1 of this.state.effects) BATCH.handlers.add(effect$1);
168
+ for (const [, subscription] of this.state.subscriptions) subscription.callback(value);
169
+ }
170
+ this.effect.dirty = false;
171
+ });
172
+ }
173
+ get() {
174
+ if (ACTIVE.computed != null && this !== ACTIVE.computed) this.state.computeds.add(ACTIVE.computed);
175
+ if (ACTIVE.effect != null && ACTIVE.effect !== this.effect.instance) this.state.effects.add(ACTIVE.effect);
176
+ if (this.effect.dirty && BATCH.depth === 0) runEffect(this.effect.instance);
177
+ return this.state.value;
178
+ }
179
+ };
180
+ function computed(callback, options) {
181
+ return new Computed(callback, options);
182
+ }
183
+ //#endregion
184
+ //#region node_modules/@oscarpalmer/mora/dist/helpers/value.js
185
+ function emitValue(state) {
186
+ for (const computed of state.computeds) computed.effect.dirty = true;
187
+ for (const effect of state.effects) BATCH.handlers.add(effect);
188
+ for (const [, subscription] of state.subscriptions) BATCH.handlers.add(subscription);
189
+ if (BATCH.depth === 0) flushHandlers();
190
+ }
191
+ function equalArrays(state, first, second) {
192
+ let { length } = first;
193
+ if (length !== second.length) return false;
194
+ let offset = 0;
195
+ if (length >= 100) {
196
+ offset = Math.round(length / 10);
197
+ offset = offset > 25 ? 25 : offset;
198
+ for (let index = 0; index < offset; index += 1) if (!state.equal(first[index], second[index])) return false;
199
+ }
200
+ length -= offset;
201
+ for (let index = offset; index < length; index += 1) if (!state.equal(first[index], second[index])) return false;
202
+ return true;
203
+ }
204
+ function getValue$1(state) {
205
+ if (ACTIVE.computed != null) state.computeds.add(ACTIVE.computed);
206
+ if (ACTIVE.effect != null) state.effects.add(ACTIVE.effect);
207
+ return state.value;
208
+ }
209
+ //#endregion
210
+ //#region node_modules/@oscarpalmer/mora/dist/value/signal.js
211
+ var Signal = class extends Reactive {
212
+ constructor(value, options) {
213
+ super(NAME_SIGNAL, value, options);
214
+ }
215
+ get() {
216
+ return getValue$1(this.state);
217
+ }
218
+ set(value) {
219
+ if (!this.state.equal(this.state.value, value)) {
220
+ this.state.value = value;
221
+ emitValue(this.state);
222
+ }
223
+ }
224
+ update(callback) {
225
+ this.set(callback(this.state.value));
226
+ }
227
+ };
228
+ function signal(value, options) {
229
+ return new Signal(value, options);
230
+ }
231
+ //#endregion
232
+ //#region node_modules/@oscarpalmer/mora/dist/helpers/proxy.js
233
+ function emityProxyValues(state, mapped) {
234
+ const values = [...mapped.values()];
235
+ const { length } = values;
236
+ for (let index = 0; index < length; index += 1) values[index].effect.dirty = true;
237
+ emitValue(state);
238
+ }
239
+ function getReactiveValueInProxy(reactive, mapped, key, isArray) {
240
+ let item = mapped.get(key);
241
+ if (item == null) {
242
+ item = computed(() => isArray ? reactive.get().at(key) : reactive.get()[key]);
243
+ mapped.set(key, item);
244
+ }
245
+ return item;
246
+ }
247
+ function setProxyValue(proxy, value) {
248
+ startBatch();
249
+ const proxyKeys = Object.keys(proxy);
250
+ const valueKeys = Object.keys(value);
251
+ let { length } = proxyKeys;
252
+ for (let index = 0; index < length; index += 1) {
253
+ const key = proxyKeys[index];
254
+ proxy[key] = valueKeys.includes(key) ? value[key] : void 0;
255
+ }
256
+ length = valueKeys.length;
257
+ for (let index = 0; index < length; index += 1) {
258
+ const key = valueKeys[index];
259
+ if (!proxyKeys.includes(key)) proxy[key] = value[key];
260
+ }
261
+ stopBatch();
262
+ }
263
+ function setValueInProxy(parameters) {
264
+ const { isArray, length, property, state, target, value } = parameters;
265
+ if (isArray) {
266
+ if (!(!Number.isNaN(Number(property)) || property === "length")) return Reflect.set(target, property, value);
267
+ }
268
+ const previous = Reflect.get(target, property);
269
+ if (!state.equal(previous, value)) {
270
+ Reflect.set(target, property, value);
271
+ emitValue(state);
272
+ if (isArray) length?.set(target.length);
273
+ }
274
+ return true;
275
+ }
276
+ //#endregion
277
+ //#region node_modules/@oscarpalmer/mora/dist/value/array.js
278
+ var ReactiveArray = class extends Reactive {
279
+ #indiced = /* @__PURE__ */ new Map();
280
+ #size = signal(0);
281
+ get length() {
282
+ return this.#size.get();
283
+ }
284
+ set length(value) {
285
+ if (typeof value === "number" && value >= 0 && value !== this.state.value.length) this.get().length = value;
286
+ }
287
+ constructor(value, options) {
288
+ super(NAME_ARRAY, new Proxy(value, {
289
+ get: (target, property) => METHODS_UPDATE.has(property) ? updateArray(property, target, this.state, this.#size) : Reflect.get(target, property),
290
+ set: (target, property, value$1) => setValueInProxy({
291
+ property,
292
+ target,
293
+ value: value$1,
294
+ isArray: true,
295
+ state: this.state,
296
+ length: this.#size
297
+ })
298
+ }), options);
299
+ this.#size.set(value.length);
300
+ }
301
+ clear() {
302
+ this.length = 0;
303
+ }
304
+ filter(callback) {
305
+ return computed(() => this.get().filter(callback));
306
+ }
307
+ get(first) {
308
+ if (typeof first === "number") return getReactiveValueInProxy(this, this.#indiced, first, true).get();
309
+ return first === "length" ? this.length : getValue$1(this.state);
310
+ }
311
+ map(callback) {
312
+ return computed(() => this.get().map(callback));
313
+ }
314
+ notify() {
315
+ emityProxyValues(this.state, this.#indiced);
316
+ }
317
+ peek(value) {
318
+ if (value === "length") return this.#size.peek();
319
+ return typeof value === "number" ? this.state.value.at(value) : [...this.state.value];
320
+ }
321
+ pop() {
322
+ return this.state.value.pop();
323
+ }
324
+ push(...items) {
325
+ return this.state.value.push(...items);
326
+ }
327
+ set(first, second) {
328
+ if (first == null || Array.isArray(first)) this.state.value.splice(0, this.state.value.length, ...first ?? []);
329
+ else if (first === "length") this.length = second;
330
+ else if (typeof first === "number" && !Number.isNaN(first)) setAtIndex(this.state.value, first, second);
331
+ }
332
+ shift() {
333
+ return this.state.value.shift();
334
+ }
335
+ splice(from, to, ...items) {
336
+ return this.state.value.splice(from, to ?? this.state.value.length, ...items);
337
+ }
338
+ subscribe(first, second) {
339
+ if (typeof first === "number" && typeof second === "function") return getReactiveValueInProxy(this, this.#indiced, first, true).subscribe(second);
340
+ return typeof first === "function" ? subscribe(this.state, first) : noop$1;
341
+ }
342
+ unshift(...items) {
343
+ return this.state.value.unshift(...items);
344
+ }
345
+ update(callback) {
346
+ const updated = callback(this.state.value);
347
+ if (updated == null || Array.isArray(updated)) this.set(updated);
348
+ }
349
+ };
350
+ function array(value, options) {
351
+ return new ReactiveArray(Array.isArray(value) ? value : [], options);
352
+ }
353
+ function updateArray(type, array$1, state, length) {
354
+ const affectsLength = METHODS_AFFECTING_LENGTH.has(type);
355
+ const previousArray = affectsLength ? [] : [...array$1];
356
+ const previousLength = array$1.length;
357
+ return (...args) => {
358
+ const result = array$1[type](...args);
359
+ if (affectsLength ? array$1.length !== previousLength : !equalArrays(state, previousArray, array$1)) {
360
+ emitValue(state);
361
+ length.set(array$1.length);
362
+ }
363
+ return result;
364
+ };
365
+ }
366
+ function setAtIndex(array$1, index, value) {
367
+ const actual = index < 0 ? array$1.length + index : index;
368
+ if (actual > -1) array$1[actual] = value;
369
+ }
370
+ //#endregion
371
+ //#region node_modules/@oscarpalmer/mora/node_modules/@oscarpalmer/atoms/dist/internal/is.js
372
+ function isKey(value) {
373
+ return typeof value === "number" || typeof value === "string";
374
+ }
375
+ function isPlainObject$1(value) {
376
+ if (value === null || typeof value !== "object") return false;
377
+ if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
378
+ const prototype = Object.getPrototypeOf(value);
379
+ return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
380
+ }
381
+ //#endregion
382
+ //#region node_modules/@oscarpalmer/mora/dist/value/store.js
383
+ var Store = class extends Reactive {
384
+ #keyed = /* @__PURE__ */ new Map();
385
+ constructor(value, options) {
386
+ super(NAME_STORE, new Proxy(value, { set: (target, property, value$1) => setValueInProxy({
387
+ target,
388
+ property,
389
+ value: value$1,
390
+ isArray: false,
391
+ state: this.state
392
+ }) }), options);
393
+ }
394
+ get(key) {
395
+ return isKey(key) ? getReactiveValueInProxy(this, this.#keyed, key, false).get() : getValue$1(this.state);
396
+ }
397
+ notify() {
398
+ emityProxyValues(this.state, this.#keyed);
399
+ }
400
+ peek(key) {
401
+ return isKey(key) ? this.state.value[key] : { ...this.state.value };
402
+ }
403
+ set(first, second) {
404
+ if (isKey(first)) this.state.value[first] = second;
405
+ else if (first == null || isPlainObject$1(first)) setProxyValue(this.state.value, first ?? {});
406
+ }
407
+ subscribe(first, second) {
408
+ if (isKey(first) && typeof second === "function") return getReactiveValueInProxy(this, this.#keyed, first, false).subscribe(second);
409
+ return typeof first === "function" ? subscribe(this.state, first) : noop$1;
410
+ }
411
+ update(callback) {
412
+ const updated = callback({ ...this.state.value });
413
+ if (updated == null || isPlainObject$1(updated)) setProxyValue(this.state.value, updated ?? {});
414
+ }
415
+ };
416
+ function store(value, options) {
417
+ return new Store(isPlainObject$1(value) ? value : {}, options);
418
+ }
419
+ //#endregion
420
+ //#region node_modules/@oscarpalmer/atoms/dist/internal/is.mjs
421
+ /**
422
+ * Is the value a plain object?
423
+ * @param value Value to check
424
+ * @returns `true` if the value is a plain object, otherwise `false`
425
+ */
426
+ function isPlainObject(value) {
427
+ if (value === null || typeof value !== "object") return false;
428
+ if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
429
+ const prototype = Object.getPrototypeOf(value);
430
+ return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
431
+ }
432
+ //#endregion
433
+ //#region node_modules/@oscarpalmer/atoms/dist/internal/string.mjs
434
+ /**
435
+ * Get the string value from any value
436
+ * @param value Original value
437
+ * @returns String representation of the value
438
+ */
439
+ function getString(value) {
440
+ if (typeof value === "string") return value;
441
+ if (value == null) return "";
442
+ if (typeof value === "function") return getString(value());
443
+ if (typeof value !== "object") return String(value);
444
+ const asString = String(value.valueOf?.() ?? value);
445
+ return asString.startsWith("[object ") ? JSON.stringify(value) : asString;
446
+ }
447
+ //#endregion
448
+ //#region node_modules/@oscarpalmer/atoms/dist/is.mjs
449
+ /**
450
+ * Is the value `undefined`, `null`, or a whitespace-only string?
451
+ * @param value Value to check
452
+ * @returns `true` if the value is nullable or a whitespace-only string, otherwise `false`
453
+ */
454
+ function isNullableOrWhitespace(value) {
455
+ return value == null || EXPRESSION_WHITESPACE$1.test(getString(value));
456
+ }
457
+ const EXPRESSION_WHITESPACE$1 = /^\s*$/;
458
+ //#endregion
459
+ //#region node_modules/@oscarpalmer/toretto/dist/internal/is.mjs
460
+ /**
461
+ * Is the value an event target?
462
+ * @param value Value to check
463
+ * @returns `true` if it's an event target, otherwise `false`
464
+ */
465
+ function isEventTarget(value) {
466
+ return typeof value === "object" && value != null && typeof value.addEventListener === "function" && typeof value.removeEventListener === "function" && typeof value.dispatchEvent === "function";
467
+ }
468
+ /**
469
+ * Is the value an HTML or SVG element?
470
+ * @param value Value to check
471
+ * @returns `true` if it's an HTML or SVG element, otherwise `false`
472
+ */
473
+ function isHTMLOrSVGElement(value) {
474
+ return value instanceof HTMLElement || value instanceof SVGElement;
475
+ }
476
+ //#endregion
477
+ //#region node_modules/@oscarpalmer/toretto/dist/is.mjs
478
+ /**
479
+ * Is the value a child node?
480
+ * @param value Value to check
481
+ * @returns `true` if it's a child node, otherwise `false`
482
+ */
483
+ function isChildNode(value) {
484
+ return value instanceof Node && CHILD_NODE_TYPES.has(value.nodeType);
485
+ }
486
+ const CHILD_NODE_TYPES = new Set([
487
+ Node.ELEMENT_NODE,
488
+ Node.TEXT_NODE,
489
+ Node.PROCESSING_INSTRUCTION_NODE,
490
+ Node.COMMENT_NODE,
491
+ Node.DOCUMENT_TYPE_NODE
492
+ ]);
493
+ //#endregion
494
+ //#region node_modules/@oscarpalmer/toretto/dist/internal/element-value.mjs
495
+ function setElementValue(element, first, second, third, callback) {
496
+ if (!isHTMLOrSVGElement(element)) return;
497
+ if (typeof first === "string") setElementValues(element, first, second, third, callback);
498
+ else if (isAttribute(first)) setElementValues(element, first.name, first.value, third, callback);
499
+ }
500
+ function setElementValues(element, first, second, third, callback) {
501
+ if (!isHTMLOrSVGElement(element)) return;
502
+ if (typeof first === "string") {
503
+ callback(element, first, second, third);
504
+ return;
505
+ }
506
+ const isArray = Array.isArray(first);
507
+ if (!isArray && !(typeof first === "object" && first !== null)) return;
508
+ const entries = isArray ? first : Object.entries(first).map(([name, value]) => ({
509
+ name,
510
+ value
511
+ }));
512
+ const { length } = entries;
513
+ for (let index = 0; index < length; index += 1) {
514
+ const entry = entries[index];
515
+ if (typeof entry === "object" && typeof entry?.name === "string") callback(element, entry.name, entry.value, third);
516
+ }
517
+ }
518
+ function updateElementValue(element, key, value, set, remove, isBoolean, json) {
519
+ if (isBoolean ? value == null : isNullableOrWhitespace(value)) remove.call(element, key);
520
+ else set.call(element, key, json ? JSON.stringify(value) : String(value));
521
+ }
522
+ //#endregion
523
+ //#region node_modules/@oscarpalmer/toretto/dist/internal/attribute.mjs
524
+ function badAttributeHandler(name, value) {
525
+ if (typeof name !== "string" || name.trim().length === 0 || typeof value !== "string") return true;
526
+ if (EXPRESSION_CLOBBERED_NAME.test(name) && (value in document || value in formElement) || EXPRESSION_EVENT_NAME$1.test(name)) return true;
527
+ if (EXPRESSION_SKIP_NAME.test(name) || EXPRESSION_URI_VALUE.test(value) || isValidSourceAttribute(name, value)) return false;
528
+ return EXPRESSION_DATA_OR_SCRIPT.test(value);
529
+ }
530
+ function booleanAttributeHandler(name, value) {
531
+ if (typeof name !== "string" || name.trim().length === 0 || typeof value !== "string") return true;
532
+ const normalizedName = name.toLowerCase();
533
+ if (!booleanAttributesSet.has(normalizedName)) return false;
534
+ const normalized = value.toLowerCase();
535
+ return !(normalized.length === 0 || normalized === normalizedName);
536
+ }
537
+ function decodeAttribute(value) {
538
+ textArea ??= document.createElement("textarea");
539
+ textArea.innerHTML = value;
540
+ return decodeURIComponent(textArea.value);
541
+ }
542
+ function handleAttribute(callback, decode, first, second) {
543
+ let name;
544
+ let value;
545
+ if (isAttribute(first)) {
546
+ name = first.name;
547
+ value = String(first.value);
548
+ } else if (typeof first === "string" && typeof second === "string") {
549
+ name = first;
550
+ value = second;
551
+ }
552
+ if (decode && value != null) value = decodeAttribute(value);
553
+ return callback(name, value?.replace(EXPRESSION_WHITESPACE, ""));
554
+ }
555
+ function isAttribute(value) {
556
+ return value instanceof Attr || isPlainObject(value) && typeof value.name === "string" && "value" in value;
557
+ }
558
+ function _isBadAttribute(first, second, decode) {
559
+ return handleAttribute(badAttributeHandler, decode, first, second);
560
+ }
561
+ function _isBooleanAttribute(first, decode) {
562
+ return handleAttribute((name) => booleanAttributesSet.has(name?.toLowerCase()), decode, first, "");
563
+ }
564
+ function _isEmptyNonBooleanAttribute(first, second, decode) {
565
+ return handleAttribute((name, value) => name != null && value != null && !booleanAttributesSet.has(name) && value.trim().length === 0, decode, first, second);
566
+ }
567
+ function _isInvalidBooleanAttribute(first, second, decode) {
568
+ return handleAttribute(booleanAttributeHandler, decode, first, second);
569
+ }
570
+ function isValidSourceAttribute(name, value) {
571
+ return EXPRESSION_SOURCE_NAME.test(name) && EXPRESSION_SOURCE_VALUE.test(value);
572
+ }
573
+ function updateAttribute(element, name, value, dispatch) {
574
+ const normalizedName = name.toLowerCase();
575
+ const isBoolean = booleanAttributesSet.has(normalizedName);
576
+ const next = isBoolean ? value === true || typeof value === "string" && (value === "" || value.toLowerCase() === normalizedName) : value == null ? "" : value;
577
+ if (name in element) updateProperty$1(element, normalizedName, next, dispatch);
578
+ updateElementValue(element, name, isBoolean ? next ? "" : null : value, element.setAttribute, element.removeAttribute, isBoolean, false);
579
+ }
580
+ function updateProperty$1(element, name, value, dispatch) {
581
+ if (Object.is(element[name], value)) return;
582
+ element[name] = value;
583
+ const event = dispatch !== false && elementEvents[element.tagName]?.[name];
584
+ if (typeof event === "string") element.dispatchEvent(new Event(event, { bubbles: true }));
585
+ }
586
+ const EXPRESSION_CLOBBERED_NAME = /^(id|name)$/i;
587
+ const EXPRESSION_DATA_OR_SCRIPT = /^(?:data|\w+script):/i;
588
+ const EXPRESSION_EVENT_NAME$1 = /^on/i;
589
+ const EXPRESSION_SKIP_NAME = /^(aria-[-\w]+|data-[-\w.\u00B7-\uFFFF]+)$/i;
590
+ const EXPRESSION_SOURCE_NAME = /^src$/i;
591
+ const EXPRESSION_SOURCE_VALUE = /^data:/i;
592
+ const EXPRESSION_URI_VALUE = /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.-]+(?:[^a-z+.\-:]|$))/i;
593
+ const EXPRESSION_WHITESPACE = /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g;
594
+ /**
595
+ * List of boolean attributes
596
+ */
597
+ const booleanAttributes = Object.freeze([
598
+ "async",
599
+ "autofocus",
600
+ "autoplay",
601
+ "checked",
602
+ "controls",
603
+ "default",
604
+ "defer",
605
+ "disabled",
606
+ "formnovalidate",
607
+ "hidden",
608
+ "inert",
609
+ "ismap",
610
+ "itemscope",
611
+ "loop",
612
+ "multiple",
613
+ "muted",
614
+ "nomodule",
615
+ "novalidate",
616
+ "open",
617
+ "playsinline",
618
+ "readonly",
619
+ "required",
620
+ "reversed",
621
+ "selected"
622
+ ]);
623
+ const booleanAttributesSet = new Set(booleanAttributes);
624
+ const elementEvents = {
625
+ DETAILS: { open: "toggle" },
626
+ INPUT: {
627
+ checked: "change",
628
+ value: "input"
629
+ },
630
+ SELECT: { value: "change" },
631
+ TEXTAREA: { value: "input" }
632
+ };
633
+ const formElement = document.createElement("form");
634
+ let textArea;
635
+ //#endregion
636
+ //#region node_modules/@oscarpalmer/toretto/dist/attribute/set.mjs
637
+ function setAttribute$1(element, first, second, third) {
638
+ setElementValue(element, first, second, third, updateAttribute);
639
+ }
640
+ //#endregion
641
+ //#region node_modules/@oscarpalmer/toretto/dist/html/sanitize.mjs
642
+ function handleElement(element, depth) {
643
+ if (depth === 0) {
644
+ const removable = element.querySelectorAll(REMOVE_SELECTOR);
645
+ for (const item of removable) item.remove();
646
+ }
647
+ sanitizeAttributes(element, [...element.attributes]);
648
+ }
649
+ /**
650
+ * Is the element clobbered?
651
+ *
652
+ * Thanks, DOMPurify _(https://github.com/cure53/DOMPurify)_
653
+ */
654
+ function isClobbered(value) {
655
+ return value instanceof HTMLFormElement && (typeof value.nodeName !== "string" || typeof value.textContent !== "string" || typeof value.removeChild !== "function" || !(value.attributes instanceof NamedNodeMap) || typeof value.removeAttribute !== "function" || typeof value.setAttribute !== "function" || typeof value.namespaceURI !== "string" || typeof value.insertBefore !== "function" || typeof value.hasChildNodes !== "function");
656
+ }
657
+ function removeNode(node) {
658
+ if (typeof node.remove === "function") node.remove();
659
+ }
660
+ function sanitizeAttributes(element, attributes) {
661
+ const { length } = attributes;
662
+ for (let index = 0; index < length; index += 1) {
663
+ const { name, value } = attributes[index];
664
+ if (_isBadAttribute(name, value, false) || _isEmptyNonBooleanAttribute(name, value, false)) element.removeAttribute(name);
665
+ else if (_isInvalidBooleanAttribute(name, value, false)) setAttribute$1(element, name, true);
666
+ }
667
+ }
668
+ function sanitizeNodes(nodes, depth) {
669
+ const actual = nodes.filter((node) => node instanceof Node);
670
+ let { length } = nodes;
671
+ for (let index = 0; index < length; index += 1) {
672
+ const node = actual[index];
673
+ let remove = isClobbered(node);
674
+ if (!remove) switch (node.nodeType) {
675
+ case Node.ELEMENT_NODE:
676
+ handleElement(node, depth);
677
+ break;
678
+ case Node.COMMENT_NODE:
679
+ remove = COMMENT_HARMFUL.test(node.data);
680
+ break;
681
+ case Node.DOCUMENT_TYPE_NODE:
682
+ case Node.PROCESSING_INSTRUCTION_NODE:
683
+ remove = true;
684
+ break;
685
+ }
686
+ if (remove) {
687
+ removeNode(node);
688
+ actual.splice(index, 1);
689
+ index -= 1;
690
+ length -= 1;
691
+ continue;
692
+ }
693
+ if (node.hasChildNodes()) sanitizeNodes([...node.childNodes], depth + 1);
694
+ }
695
+ return nodes;
696
+ }
697
+ const COMMENT_HARMFUL = /<[/\w]/g;
698
+ const REMOVE_SELECTOR = "script, toretto-temporary";
699
+ //#endregion
700
+ //#region node_modules/@oscarpalmer/toretto/dist/html/index.mjs
701
+ function createHtml(value) {
702
+ const parsed = getParser().parseFromString(getHtml(value), PARSE_TYPE_HTML);
703
+ parsed.body.normalize();
704
+ sanitizeNodes([parsed.body], 0);
705
+ return parsed.body.innerHTML;
706
+ }
707
+ function createTemplate(value, options) {
708
+ const template = document.createElement(TEMPLATE_TAG);
709
+ template.innerHTML = createHtml(value);
710
+ if (typeof value === "string" && options.cache) templates[value] = template;
711
+ return template;
712
+ }
713
+ function getHtml(value) {
714
+ return `${TEMPORARY_ELEMENT}${typeof value === "string" ? value : value.innerHTML}${TEMPORARY_ELEMENT}`;
715
+ }
716
+ function getNodes(value, options) {
717
+ if (typeof value !== "string" && !(value instanceof HTMLTemplateElement)) return [];
718
+ const template = getTemplate(value, options);
719
+ return template == null ? [] : [...template.content.cloneNode(true).childNodes];
720
+ }
721
+ function getOptions$1(input) {
722
+ const options = isPlainObject(input) ? input : {};
723
+ options.cache = typeof options.cache === "boolean" ? options.cache : true;
724
+ return options;
725
+ }
726
+ function getParser() {
727
+ parser ??= new DOMParser();
728
+ return parser;
729
+ }
730
+ function getTemplate(value, options) {
731
+ if (value instanceof HTMLTemplateElement) return createTemplate(value, options);
732
+ if (value.trim().length === 0) return;
733
+ let template = templates[value];
734
+ if (template != null) return template;
735
+ const element = EXPRESSION_ID.test(value) ? document.querySelector(`#${value}`) : null;
736
+ return createTemplate(element instanceof HTMLTemplateElement ? element : value, options);
737
+ }
738
+ const html$1 = ((value, options) => {
739
+ return getNodes(value, getOptions$1(options));
740
+ });
741
+ html$1.clear = () => {
742
+ templates = {};
743
+ };
744
+ html$1.remove = (template) => {
745
+ if (typeof template !== "string" || templates[template] == null) return;
746
+ const keys = Object.keys(templates);
747
+ const { length } = keys;
748
+ const updated = {};
749
+ for (let index = 0; index < length; index += 1) {
750
+ const key = keys[index];
751
+ if (key !== template) updated[key] = templates[key];
752
+ }
753
+ templates = updated;
754
+ };
755
+ const EXPRESSION_ID = /^[a-z][\w-]*$/i;
756
+ const PARSE_TYPE_HTML = "text/html";
757
+ const TEMPLATE_TAG = "template";
758
+ const TEMPORARY_ELEMENT = "<toretto-temporary></toretto-temporary>";
759
+ let parser;
760
+ let templates = {};
761
+ //#endregion
762
+ //#region src/constants.ts
763
+ const EVENT_DEFAULTS = {
764
+ A: "click",
765
+ BUTTON: "click",
766
+ DETAILS: "toggle",
767
+ FORM: "submit",
768
+ SELECT: "change",
769
+ TEXTAREA: "input"
770
+ };
771
+ const EXPRESSION_ABYDON_ATTRIBUTE_FULL = /(@?\w+)="<!--abydon.(\d+)-->"/g;
772
+ const EXPRESSION_ABYDON_ATTRIBUTE_PREFIX = /^_/;
773
+ const EXPRESSION_ABYDON_CONTENT = /^@?abydon\.(\d+)@?$/;
774
+ const EXPRESSION_ATTRIBUTE_CLASS = /^class\./;
775
+ const EXPRESSION_ATTRIBUTE_STYLE_FULL = /^style\.([\w-]+)(?:\.([\w-]+))?$/;
776
+ const EXPRESSION_ATTRIBUTE_STYLE_PREFIX = /^style\./;
777
+ const EXPRESSION_EVENT_CHANGE_TYPES = /^(checkbox|radio)$/;
778
+ const EXPRESSION_EVENT_NAME = /^@([\w-]+)(?::([a-z:]+))?$/i;
779
+ const EXPRESSION_EVENT_OPTIONS_ACTIVE = /^a(ctive)$/i;
780
+ const EXPRESSION_EVENT_OPTIONS_CAPTURE = /^c(apture)$/i;
781
+ const EXPRESSION_EVENT_OPTIONS_ONCE = /^o(nce)$/i;
782
+ const EXPRESSION_EVENT_PREFIX = /^@/;
783
+ const EXPRESSION_PERIOD = /\./;
784
+ const NAME_FRAGMENT = "$fragment";
785
+ const NAME_FRAGMENTS = "$fragments";
786
+ //#endregion
787
+ //#region src/helpers/index.ts
788
+ function compareArrays(first, second) {
789
+ const firstIsLarger = first.length > second.length;
790
+ const from = firstIsLarger ? first : second;
791
+ const to = firstIsLarger ? second : first;
792
+ if (!from.filter((key) => to.includes(key)).every((key, index) => to[index] === key)) return COMPARISON_DISSIMILAR;
793
+ return firstIsLarger ? COMPARISON_REMOVED : COMPARISON_ADDED;
794
+ }
795
+ function isFragment(value) {
796
+ return isNamed(value, NAME_FRAGMENT);
797
+ }
798
+ function isFragments(value) {
799
+ return isNamed(value, NAME_FRAGMENTS);
800
+ }
801
+ function isNamed(value, name) {
802
+ return typeof value === "object" && value != null && name in value && value[name] === true;
803
+ }
804
+ const COMPARISON_ADDED = "added";
805
+ const COMPARISON_DISSIMILAR = "dissimilar";
806
+ const COMPARISON_REMOVED = "removed";
807
+ //#endregion
808
+ //#region src/fragments.ts
809
+ var Fragments = class {
810
+ #state;
811
+ /**
812
+ * Fragment items
813
+ */
814
+ get items() {
815
+ return this.#state.mapped;
816
+ }
817
+ constructor(items, identify, fragment) {
818
+ Object.defineProperty(this, NAME_FRAGMENTS, { value: true });
819
+ this.#state = {
820
+ fragment,
821
+ identify,
822
+ array: items,
823
+ instances: {},
824
+ mapped: array([]),
825
+ subscriber: void 0
826
+ };
827
+ states.set(this, this.#state);
828
+ initializeFragments(this.#state);
829
+ }
830
+ };
831
+ function handleFragments(item, remove) {
832
+ const state = isFragments(item) ? states.get(item) : item;
833
+ if (state != null) (remove ? removeFragments$1 : initializeFragments)(state);
834
+ }
835
+ function handleItems(state, items) {
836
+ const keys = /* @__PURE__ */ new Set();
837
+ const mapped = [];
838
+ const { length } = items;
839
+ for (let index = 0; index < length; index += 1) {
840
+ const item = items[index];
841
+ const identifier = state.identify(item);
842
+ if (identifier == null) throw new Error("Identifier cannot be null or undefined");
843
+ const key = getString(identifier);
844
+ if (keys.has(key)) throw new Error(`Duplicate identifier found: "${key}"`);
845
+ let instance = state.instances[key];
846
+ if (instance == null) {
847
+ instance = state.fragment(item);
848
+ if (!isFragment(instance)) throw new Error("Fragment function must return a Fragment instance");
849
+ }
850
+ instance.identify(key);
851
+ state.instances[key] = instance;
852
+ keys.add(key);
853
+ mapped.push(instance);
854
+ }
855
+ state.mapped.set(mapped);
856
+ updateFragments(state, keys);
857
+ }
858
+ function initializeFragments(state) {
859
+ state.subscriber ??= state.array.subscribe((items) => {
860
+ handleItems(state, items);
861
+ });
862
+ }
863
+ function removeFragments$1(state) {
864
+ state.subscriber?.();
865
+ updateFragments(state);
866
+ state.subscriber = void 0;
867
+ }
868
+ function updateFragments(state, active) {
869
+ const next = {};
870
+ const previous = { ...state.instances };
871
+ const keys = Object.keys(previous);
872
+ const { length } = keys;
873
+ for (let index = 0; index < length; index += 1) {
874
+ const key = keys[index];
875
+ if (active?.has(key)) next[key] = previous[key];
876
+ else previous[key].remove();
877
+ }
878
+ state.instances = next;
879
+ active?.clear();
880
+ }
881
+ const states = /* @__PURE__ */ new WeakMap();
882
+ //#endregion
883
+ //#region src/helpers/dom.ts
884
+ function createNodes(value) {
885
+ if (isFragment(value)) return value.get();
886
+ if (isChildNode(value)) return [value];
887
+ return [new Text(getString(value))];
888
+ }
889
+ function removeNodes(nodes) {
890
+ const { length } = nodes;
891
+ for (let index = 0; index < length; index += 1) nodes[index].remove();
892
+ }
893
+ function replaceNodes(from, to) {
894
+ from[0]?.replaceWith(...to);
895
+ const { length } = from;
896
+ for (let index = 1; index < length; index += 1) from[index].remove();
897
+ }
898
+ //#endregion
899
+ //#region node_modules/@oscarpalmer/toretto/dist/internal/get-value.mjs
900
+ function getBoolean(value, defaultValue) {
901
+ return typeof value === "boolean" ? value : defaultValue ?? false;
902
+ }
903
+ //#endregion
904
+ //#region node_modules/@oscarpalmer/toretto/dist/event/delegation.mjs
905
+ function addDelegatedHandler(doc, type, name, passive) {
906
+ if (DELEGATED.has(name)) return;
907
+ DELEGATED.add(name);
908
+ doc.addEventListener(type, passive ? HANDLER_PASSIVE : HANDLER_ACTIVE, { passive });
909
+ }
910
+ function addDelegatedListener(target, type, name, listener, passive) {
911
+ target[name] ??= /* @__PURE__ */ new Set();
912
+ target[name].add(listener);
913
+ addDelegatedHandler(document, type, name, passive);
914
+ return () => {
915
+ removeDelegatedListener(target, name, listener);
916
+ };
917
+ }
918
+ function delegatedEventHandler(event) {
919
+ const key = `${EVENT_PREFIX}${event.type}${this ? EVENT_SUFFIX_PASSIVE : EVENT_SUFFIX_ACTIVE}`;
920
+ const items = event.composedPath();
921
+ const { length } = items;
922
+ let target = items[0];
923
+ Object.defineProperties(event, {
924
+ currentTarget: {
925
+ configurable: true,
926
+ get() {
927
+ return target;
928
+ }
929
+ },
930
+ target: {
931
+ configurable: true,
932
+ value: target
933
+ }
934
+ });
935
+ for (let index = 0; index < length; index += 1) {
936
+ const item = items[index];
937
+ const listeners = item[key];
938
+ if (item.disabled || listeners == null) continue;
939
+ target = item;
940
+ for (const listener of listeners) {
941
+ listener.call(item, event);
942
+ if (event.cancelBubble) return;
943
+ }
944
+ }
945
+ }
946
+ function getDelegatedName(target, type, options) {
947
+ if (isEventTarget(target) && EVENT_TYPES.has(type) && !options.capture && !options.once && options.signal == null) return `${EVENT_PREFIX}${type}${options.passive ? EVENT_SUFFIX_PASSIVE : EVENT_SUFFIX_ACTIVE}`;
948
+ }
949
+ function removeDelegatedListener(target, name, listener) {
950
+ const handlers = target[name];
951
+ if (handlers == null || !handlers.has(listener)) return false;
952
+ handlers.delete(listener);
953
+ if (handlers.size === 0) target[name] = void 0;
954
+ return true;
955
+ }
956
+ const DELEGATED = /* @__PURE__ */ new Set();
957
+ const EVENT_PREFIX = "@";
958
+ const EVENT_SUFFIX_ACTIVE = ":active";
959
+ const EVENT_SUFFIX_PASSIVE = ":passive";
960
+ const EVENT_TYPES = new Set([
961
+ "beforeinput",
962
+ "click",
963
+ "dblclick",
964
+ "contextmenu",
965
+ "focusin",
966
+ "focusout",
967
+ "input",
968
+ "keydown",
969
+ "keyup",
970
+ "mousedown",
971
+ "mousemove",
972
+ "mouseout",
973
+ "mouseover",
974
+ "mouseup",
975
+ "pointerdown",
976
+ "pointermove",
977
+ "pointerout",
978
+ "pointerover",
979
+ "pointerup",
980
+ "touchend",
981
+ "touchmove",
982
+ "touchstart"
983
+ ]);
984
+ const HANDLER_ACTIVE = delegatedEventHandler.bind(false);
985
+ const HANDLER_PASSIVE = delegatedEventHandler.bind(true);
986
+ //#endregion
987
+ //#region node_modules/@oscarpalmer/atoms/dist/internal/function/misc.mjs
988
+ /**
989
+ * A function that does nothing, which can be useful, I guess…
990
+ */
991
+ function noop() {}
992
+ //#endregion
993
+ //#region node_modules/@oscarpalmer/toretto/dist/event/index.mjs
994
+ function createEventOptions(options) {
995
+ return {
996
+ capture: getBoolean(options?.capture),
997
+ once: getBoolean(options?.once),
998
+ passive: getBoolean(options?.passive, true),
999
+ signal: options?.signal instanceof AbortSignal ? options.signal : void 0
1000
+ };
1001
+ }
1002
+ function on(target, type, listener, options) {
1003
+ if (!isEventTarget(target) || typeof type !== "string" || typeof listener !== "function") return noop;
1004
+ const extended = createEventOptions(options);
1005
+ const delegated = getDelegatedName(target, type, extended);
1006
+ if (delegated != null) return addDelegatedListener(target, type, delegated, listener, extended.passive);
1007
+ target.addEventListener(type, listener, extended);
1008
+ if (extended.once) return noop;
1009
+ return () => {
1010
+ target.removeEventListener(type, listener, extended);
1011
+ };
1012
+ }
1013
+ //#endregion
1014
+ //#region src/node/event.ts
1015
+ function getOptions(options) {
1016
+ const parts = options.split(":");
1017
+ return {
1018
+ capture: parts.some((part) => EXPRESSION_EVENT_OPTIONS_CAPTURE.test(part)),
1019
+ once: parts.some((part) => EXPRESSION_EVENT_OPTIONS_ONCE.test(part)),
1020
+ passive: !parts.some((part) => EXPRESSION_EVENT_OPTIONS_ACTIVE.test(part))
1021
+ };
1022
+ }
1023
+ function getType(element, type) {
1024
+ if (type !== "on") return type;
1025
+ if (element instanceof HTMLInputElement) {
1026
+ if (EXPRESSION_EVENT_CHANGE_TYPES.test(element.type)) return "change";
1027
+ return element.type === "submit" ? "submit" : "input";
1028
+ }
1029
+ return EVENT_DEFAULTS[element.tagName] ?? type;
1030
+ }
1031
+ function mapEvent(element, name, value) {
1032
+ const [, type, options] = EXPRESSION_EVENT_NAME.exec(name) ?? [];
1033
+ if (type != null && typeof value === "function") on(element, getType(element, type), value, getOptions(options ?? ""));
1034
+ }
1035
+ //#endregion
1036
+ //#region node_modules/@oscarpalmer/toretto/dist/attribute/index.mjs
1037
+ function isBooleanAttribute(first) {
1038
+ return _isBooleanAttribute(first, true);
1039
+ }
1040
+ //#endregion
1041
+ //#region src/node/attribute/value.ts
1042
+ function getCallback(element, name) {
1043
+ if (isBooleanAttribute(name) && name in element) return name === "checked" ? updateChecked : updateProperty;
1044
+ return name === "value" ? updateValue : setAttribute$1;
1045
+ }
1046
+ function setAttribute(data, element, name, value) {
1047
+ switch (true) {
1048
+ case EXPRESSION_ATTRIBUTE_CLASS.test(name):
1049
+ setClasses(data, element, name, value);
1050
+ return;
1051
+ case EXPRESSION_ATTRIBUTE_STYLE_PREFIX.test(name):
1052
+ setStyle(data, element, name, value);
1053
+ return;
1054
+ default:
1055
+ setValue(data, element, name, value);
1056
+ break;
1057
+ }
1058
+ }
1059
+ function setClasses(data, element, name, value) {
1060
+ function update(value) {
1061
+ if (value === true) element.classList.add(...classes);
1062
+ else element.classList.remove(...classes);
1063
+ }
1064
+ const classes = name.slice(6).split(".");
1065
+ if (isReactive(value)) data.mora.subscribers.add(value.subscribe(update));
1066
+ else update(value);
1067
+ }
1068
+ function setStyle(data, element, name, value) {
1069
+ const [, property, unit] = EXPRESSION_ATTRIBUTE_STYLE_FULL.exec(name) ?? [];
1070
+ if (property == null) return;
1071
+ function update(value) {
1072
+ if (value == null || value === false || value === true && unit == null) element.style.removeProperty(property);
1073
+ else element.style.setProperty(property, value === true ? unit : String(value));
1074
+ }
1075
+ if (isReactive(value)) data.mora.subscribers.add(value.subscribe(update));
1076
+ else update(value);
1077
+ }
1078
+ function setValue(data, element, name, value) {
1079
+ const callback = getCallback(element, name);
1080
+ if (isReactive(value)) data.mora.subscribers.add(value.subscribe((next) => {
1081
+ callback(element, name, next);
1082
+ }));
1083
+ else callback(element, name, value);
1084
+ }
1085
+ function updateChecked(element, name, value) {
1086
+ updateElement("change", "checked", element, name, value, value === true);
1087
+ }
1088
+ function updateElement(event, property, element, name, value, next) {
1089
+ if (!(property in element) || element[property] === next) return;
1090
+ setAttribute$1(element, name, value);
1091
+ if (element[property] === next) return;
1092
+ element[property] = next;
1093
+ element.dispatchEvent(new Event(event, { bubbles: true }));
1094
+ }
1095
+ function updateProperty(element, name, value) {
1096
+ setAttribute$1(element, name, value === true);
1097
+ }
1098
+ function updateValue(element, name, value) {
1099
+ updateElement(element instanceof HTMLSelectElement ? "change" : "input", "value", element, name, value, String(value));
1100
+ }
1101
+ //#endregion
1102
+ //#region src/node/attribute/index.ts
1103
+ function getValue(data, original) {
1104
+ const matches = EXPRESSION_ABYDON_CONTENT.exec(original ?? "");
1105
+ return matches == null ? original : data.values[+matches[1]];
1106
+ }
1107
+ function mapAttributes(data, element) {
1108
+ const attributes = [...element.attributes];
1109
+ const { length } = attributes;
1110
+ for (let index = 0; index < length; index += 1) {
1111
+ const { name, value } = attributes[index];
1112
+ const actualName = name.replace(EXPRESSION_ABYDON_ATTRIBUTE_PREFIX, "");
1113
+ const actualValue = getValue(data, value);
1114
+ if (actualName !== name) element.removeAttribute(name);
1115
+ switch (true) {
1116
+ case EXPRESSION_EVENT_PREFIX.test(actualName):
1117
+ mapEvent(element, actualName, actualValue);
1118
+ break;
1119
+ case EXPRESSION_PERIOD.test(actualName):
1120
+ case typeof actualValue === "function":
1121
+ case isReactive(actualValue):
1122
+ mapValue$1(data, element, actualName, actualValue);
1123
+ break;
1124
+ default: break;
1125
+ }
1126
+ }
1127
+ }
1128
+ function mapValue$1(data, element, name, value) {
1129
+ if (typeof value === "function") setComputedAttribute(data, element, name, value);
1130
+ else setAttribute(data, element, name, value);
1131
+ }
1132
+ function setComputedAttribute(data, element, name, callback) {
1133
+ const value = computed(callback);
1134
+ data.mora.values.add(value);
1135
+ setAttribute(data, element, name, value);
1136
+ }
1137
+ //#endregion
1138
+ //#region src/node/value.ts
1139
+ function addToArray(identifiers, items, nodes, added) {
1140
+ let position = nodes[0];
1141
+ const before = added && !identifiers.previous.has(items.templates[0].identifier);
1142
+ const next = items.next.flatMap((fragment) => fragment.get().flatMap((node) => ({
1143
+ identifier: fragment.identifier,
1144
+ value: node
1145
+ })));
1146
+ const { length } = next;
1147
+ for (let index = 0; index < length; index += 1) {
1148
+ const node = next[index];
1149
+ if (!(added && identifiers.previous.has(node.identifier))) if (index === 0 && before) position.before(node.value);
1150
+ else position.after(node.value);
1151
+ position = node.value;
1152
+ }
1153
+ }
1154
+ function handleArray(identifiers, items, nodes) {
1155
+ const next = items.templates.map((template) => items.fragments?.find((fragment) => fragment.identifier === template.identifier) ?? template);
1156
+ const comparison = compareArrays(items.fragments ?? [], items.templates);
1157
+ if (comparison !== "removed") addToArray(identifiers, {
1158
+ ...items,
1159
+ next
1160
+ }, nodes, comparison === "added");
1161
+ const toRemove = items.fragments?.filter((fragment) => !identifiers.next.has(fragment.identifier)) ?? [];
1162
+ const { length } = toRemove;
1163
+ for (let index = 0; index < length; index += 1) toRemove[index].remove();
1164
+ return {
1165
+ fragments: next,
1166
+ nodes: next.flatMap((fragment) => fragment.get())
1167
+ };
1168
+ }
1169
+ function removeFragments(fragments) {
1170
+ if (fragments != null) {
1171
+ const { length } = fragments;
1172
+ for (let index = 0; index < length; index += 1) fragments[index].remove();
1173
+ }
1174
+ }
1175
+ function replaceText(item, comment, isNullable) {
1176
+ let to;
1177
+ if (isNullable) to = [comment];
1178
+ else to = item.text == null ? [] : [item.text];
1179
+ replaceNodes(item.nodes ?? [], to);
1180
+ }
1181
+ function setArray(item, comment, value) {
1182
+ if (value.length === 0) return { nodes: setText(item, comment, value) };
1183
+ let templates = value.filter((item) => isFragment(item) && item.identifier != null);
1184
+ const next = templates.map((fragment) => fragment.identifier);
1185
+ const previous = item.fragments?.map((fragment) => fragment.identifier) ?? [];
1186
+ if (new Set(next).size !== templates.length) templates = [];
1187
+ const noTemplates = templates.length === 0;
1188
+ if (noTemplates || item.nodes == null || previous.some((identifier) => identifier == null)) return {
1189
+ fragments: noTemplates ? void 0 : templates,
1190
+ nodes: setNodes(item, comment, noTemplates ? value.flatMap((item) => createNodes(item)) : templates.flatMap((template) => template.get()))
1191
+ };
1192
+ return handleArray({
1193
+ next: new Set(next),
1194
+ previous: new Set(previous)
1195
+ }, {
1196
+ templates,
1197
+ fragments: item.fragments ?? []
1198
+ }, item.nodes);
1199
+ }
1200
+ function setNodes(item, comment, next) {
1201
+ if (item.nodes == null) {
1202
+ if (comment.parentNode != null) replaceNodes([comment], next);
1203
+ else if (item.text?.parentNode != null) replaceNodes([item.text], next);
1204
+ } else replaceNodes(item.nodes, next);
1205
+ removeFragments(item.fragments);
1206
+ return next;
1207
+ }
1208
+ function setReactiveValue(data, comment, reactive) {
1209
+ let item = data.items.find((item) => item.nodes?.includes(comment));
1210
+ item ??= {};
1211
+ item.text = new Text();
1212
+ data.mora.subscribers.add(reactive.subscribe((value) => {
1213
+ if (Array.isArray(value)) setReactiveValueForArray(item, comment, value);
1214
+ else setReactiveValueForSingle(item, comment, value);
1215
+ item.nodes = [...item.nodes ?? [comment]];
1216
+ }));
1217
+ }
1218
+ function setReactiveValueForArray(item, comment, value) {
1219
+ const result = setArray(item, comment, value);
1220
+ item.fragments = typeof result === "boolean" ? void 0 : result?.fragments;
1221
+ if (typeof result === "boolean") if (result) item.nodes = item.text == null ? [] : [item.text];
1222
+ else item.nodes = void 0;
1223
+ else item.nodes = result?.nodes;
1224
+ }
1225
+ function setReactiveValueForSingle(item, comment, value) {
1226
+ const valueIsFragment = isFragment(value);
1227
+ item.fragments = valueIsFragment ? [value] : void 0;
1228
+ if (valueIsFragment || isChildNode(value)) item.nodes = setNodes(item, comment, createNodes(value));
1229
+ else item.nodes = setText(item, comment, value);
1230
+ }
1231
+ function setText(item, comment, value) {
1232
+ const isNullable = isNullableOrWhitespace(value);
1233
+ if (item.text != null) item.text.textContent = isNullable ? "" : getString(value);
1234
+ let result = false;
1235
+ if (item.nodes != null) {
1236
+ replaceText(item, comment, isNullable);
1237
+ result = !isNullable;
1238
+ } else if (isNullable && comment.parentNode == null) item.text?.replaceWith(comment);
1239
+ else if (!isNullable && item?.text?.parentNode == null) {
1240
+ if (item.text != null) comment.replaceWith(item.text);
1241
+ result = true;
1242
+ }
1243
+ removeFragments(item.fragments);
1244
+ if (result) return item.text == null ? [] : [item.text];
1245
+ }
1246
+ //#endregion
1247
+ //#region src/node/index.ts
1248
+ function mapNode(data, comment) {
1249
+ const matches = EXPRESSION_ABYDON_CONTENT.exec(comment.textContent ?? "");
1250
+ const value = matches == null ? null : data.values[+matches[1]];
1251
+ if (value != null) mapValue(data, comment, value);
1252
+ }
1253
+ function mapNodes(data, nodes) {
1254
+ const { length } = nodes;
1255
+ for (let index = 0; index < length; index += 1) {
1256
+ const node = nodes[index];
1257
+ if (node instanceof Comment) {
1258
+ mapNode(data, node);
1259
+ continue;
1260
+ }
1261
+ if (isHTMLOrSVGElement(node)) mapAttributes(data, node);
1262
+ if (node.hasChildNodes()) mapNodes(data, [...node.childNodes]);
1263
+ }
1264
+ }
1265
+ function mapValue(data, comment, value) {
1266
+ switch (true) {
1267
+ case typeof value === "function":
1268
+ setComputedValue(data, comment, value);
1269
+ break;
1270
+ case isFragments(value):
1271
+ handleFragments(value, false);
1272
+ setReactiveValue(data, comment, value.items);
1273
+ break;
1274
+ case isReactive(value):
1275
+ setReactiveValue(data, comment, value);
1276
+ break;
1277
+ default:
1278
+ replaceComment(data, comment, value);
1279
+ break;
1280
+ }
1281
+ }
1282
+ function replaceComment(data, comment, value) {
1283
+ const item = data.items.find((item) => item.nodes?.includes(comment));
1284
+ const nodes = createNodes(value);
1285
+ if (item != null) {
1286
+ item.fragments = isFragment(value) ? [value] : void 0;
1287
+ item.nodes = nodes;
1288
+ }
1289
+ comment.replaceWith(...nodes);
1290
+ }
1291
+ function setComputedValue(data, comment, callback) {
1292
+ const value = computed(callback);
1293
+ data.mora.values.add(value);
1294
+ setReactiveValue(data, comment, value);
1295
+ }
1296
+ //#endregion
1297
+ //#region src/parse.ts
1298
+ function handleExpression(data, prefix, expression) {
1299
+ if (Array.isArray(expression)) {
1300
+ const { length } = expression;
1301
+ let expressions = "";
1302
+ for (let index = 0; index < length; index += 1) expressions += handleExpression(data, "", expression[index]);
1303
+ return `${prefix}${expressions}`;
1304
+ }
1305
+ if (typeof expression === "function" || typeof expression === "object" && expression != null) return transformExpression(prefix, data.values.push(expression) - 1);
1306
+ return isNullableOrWhitespace(expression) ? prefix : `${prefix}${expression}`;
1307
+ }
1308
+ function parse(data) {
1309
+ if (data.template != null) return data.template;
1310
+ const { length } = data.strings;
1311
+ data.template = "";
1312
+ for (let index = 0; index < length; index += 1) data.template += handleExpression(data, data.strings[index], data.expressions[index]);
1313
+ data.template = data.template.replaceAll(EXPRESSION_ABYDON_ATTRIBUTE_FULL, transformAttribute);
1314
+ data.expressions = [];
1315
+ data.strings = [];
1316
+ return data.template;
1317
+ }
1318
+ function transformAttribute(_, name, index) {
1319
+ return `_${name}="@abydon.${index}@"`;
1320
+ }
1321
+ function transformExpression(prefix, index) {
1322
+ return `${prefix}<!--abydon.${index}-->`;
1323
+ }
1324
+ //#endregion
1325
+ //#region src/fragment.ts
1326
+ var Fragment = class {
1327
+ #data;
1328
+ #configuration = {
1329
+ identifier: void 0,
1330
+ cache: true
1331
+ };
1332
+ /**
1333
+ * Fragment identifier
1334
+ */
1335
+ get identifier() {
1336
+ return this.#configuration.identifier;
1337
+ }
1338
+ constructor(strings, expressions) {
1339
+ Object.defineProperty(this, NAME_FRAGMENT, { value: true });
1340
+ this.#data = {
1341
+ expressions,
1342
+ strings,
1343
+ items: [],
1344
+ mora: {
1345
+ subscribers: /* @__PURE__ */ new Set(),
1346
+ values: /* @__PURE__ */ new Set()
1347
+ },
1348
+ values: []
1349
+ };
1350
+ }
1351
+ /**
1352
+ * Append the fragment to the given element
1353
+ * @param element Element to append to
1354
+ */
1355
+ appendTo(element) {
1356
+ element.append(...this.get());
1357
+ }
1358
+ /**
1359
+ * Configure the fragment
1360
+ * @param configuration Configuration options
1361
+ * @returns Fragment
1362
+ */
1363
+ configure(configuration) {
1364
+ const actual = isPlainObject(configuration) ? configuration : {};
1365
+ if ("identifier" in actual) this.#configuration.identifier = actual.identifier;
1366
+ if (typeof actual.cache === "boolean") this.#configuration.cache = actual.cache;
1367
+ return this;
1368
+ }
1369
+ /**
1370
+ * Get a list of the fragment's nodes
1371
+ * @returns List of nodes
1372
+ */
1373
+ get() {
1374
+ const data = this.#data;
1375
+ if (data.items.length === 0) {
1376
+ const templated = html$1(parse(data), { cache: this.#configuration.cache });
1377
+ data.items.splice(0, data.items.length, ...templated.map((node) => ({ nodes: [node] })));
1378
+ mapNodes(data, data.items.flatMap((item) => item.fragments?.flatMap((fragment) => fragment.get()) ?? item.nodes ?? []));
1379
+ }
1380
+ return data.items.flatMap((item) => item.fragments?.flatMap((fragment) => fragment.get()) ?? item.nodes ?? []);
1381
+ }
1382
+ /**
1383
+ * Set an identifier for the fragment
1384
+ *
1385
+ * _An identifier can be used to uniquely identify a fragment,
1386
+ * which helps prevent re-rendering in certain scenarios._
1387
+ * @param identifier Identifier
1388
+ * @returns Fragment
1389
+ */
1390
+ identify(identifier) {
1391
+ this.#configuration.identifier = identifier;
1392
+ return this;
1393
+ }
1394
+ /**
1395
+ * Remove the fragment from the DOM
1396
+ */
1397
+ remove() {
1398
+ removeFragment(this.#data);
1399
+ }
1400
+ };
1401
+ function removeFragment(data) {
1402
+ removeMora(data);
1403
+ let { length } = data.items;
1404
+ for (let index = 0; index < length; index += 1) {
1405
+ const { fragments, nodes } = data.items[index];
1406
+ const fragmentsLength = fragments?.length ?? 0;
1407
+ for (let fragmentIndex = 0; fragmentIndex < fragmentsLength; fragmentIndex += 1) fragments?.[fragmentIndex]?.remove();
1408
+ removeNodes(nodes ?? []);
1409
+ }
1410
+ data.items.length = 0;
1411
+ length = data.values.length;
1412
+ for (let index = 0; index < length; index += 1) {
1413
+ const value = data.values[index];
1414
+ if (isFragments(value)) handleFragments(value, true);
1415
+ }
1416
+ }
1417
+ function removeMora(data) {
1418
+ const unsubscribers = [...data.mora.subscribers];
1419
+ data.mora.subscribers.clear();
1420
+ data.mora.values.clear();
1421
+ for (const unsubscribe of unsubscribers) unsubscribe();
1422
+ }
1423
+ //#endregion
1424
+ //#region src/index.ts
1425
+ /**
1426
+ * Create Fragments from a reactive array
1427
+ * @param array Reactive array
1428
+ * @param identify Function to identify item
1429
+ * @param fragment Function to create fragment from item
1430
+ * @returns Fragments
1431
+ */
1432
+ function fragments(array, identify, fragment) {
1433
+ return new Fragments(array, identify, fragment);
1434
+ }
1435
+ /**
1436
+ * Create Fragment from a template
1437
+ * @returns Fragment
1438
+ */
1439
+ function html(template, ...values) {
1440
+ return new Fragment(template, values);
1441
+ }
1442
+ //#endregion
1443
+ export { array, computed, effect, fragments, html, isArray, isComputed, isEffect, isReactive, isSignal, signal, startBatch, stopBatch, store };