@baleada/logic 0.22.7 → 0.23.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.cjs +2229 -508
- package/lib/index.d.ts +511 -73
- package/lib/index.js +2172 -500
- package/package.json +28 -16
package/lib/index.js
CHANGED
|
@@ -1,50 +1,55 @@
|
|
|
1
|
-
import { reduce, pipe, unique, toArray, slice, filter, map, concat, find, findIndex, join, some, every } from 'lazy-collections';
|
|
2
|
-
import slugify from '@sindresorhus/slugify';
|
|
3
1
|
import BezierEasing from 'bezier-easing';
|
|
4
2
|
import { mix } from '@snigo.dev/color';
|
|
3
|
+
import { pipe, concat, toArray, filter, map, reduce, slice, sort, unique, find, findIndex, join, at, includes, some, every, flatMap, reverse as reverse$1 } from 'lazy-collections';
|
|
5
4
|
import { getStroke } from 'perfect-freehand';
|
|
6
5
|
import polygonClipping from 'polygon-clipping';
|
|
6
|
+
import ky from 'ky';
|
|
7
7
|
import createDOMPurify from 'dompurify';
|
|
8
8
|
import { Searcher } from 'fast-fuzzy';
|
|
9
|
+
import { klona } from 'klona';
|
|
10
|
+
import { dequal } from 'dequal';
|
|
11
|
+
import slugify from '@sindresorhus/slugify';
|
|
12
|
+
import clsx from 'clsx';
|
|
9
13
|
|
|
10
|
-
function
|
|
11
|
-
return
|
|
12
|
-
return
|
|
13
|
-
async (accumulatorPromise, item, index) => {
|
|
14
|
-
const accumulator = await accumulatorPromise;
|
|
15
|
-
return accumulate(accumulator, item, index);
|
|
16
|
-
},
|
|
17
|
-
Promise.resolve(initialValue)
|
|
18
|
-
)(array);
|
|
14
|
+
function createClone() {
|
|
15
|
+
return (any) => {
|
|
16
|
+
return klona(any);
|
|
19
17
|
};
|
|
20
18
|
}
|
|
21
|
-
function
|
|
22
|
-
return (
|
|
19
|
+
function createEqual(compared) {
|
|
20
|
+
return (any) => dequal(any, compared);
|
|
23
21
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
22
|
+
|
|
23
|
+
function createConcat(...arrays) {
|
|
24
|
+
return (array) => pipe(
|
|
25
|
+
concat(array, ...arrays),
|
|
26
|
+
toArray()
|
|
27
|
+
)();
|
|
29
28
|
}
|
|
30
|
-
function
|
|
31
|
-
return
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
resolvedMaps.push(transformed);
|
|
36
|
-
return resolvedMaps;
|
|
37
|
-
},
|
|
38
|
-
[]
|
|
39
|
-
)(array);
|
|
40
|
-
};
|
|
29
|
+
function createFilter(predicate) {
|
|
30
|
+
return (array) => pipe(
|
|
31
|
+
filter(predicate),
|
|
32
|
+
toArray()
|
|
33
|
+
)(array);
|
|
41
34
|
}
|
|
42
|
-
function
|
|
43
|
-
return
|
|
44
|
-
const
|
|
45
|
-
return
|
|
35
|
+
function createInsert(item, index) {
|
|
36
|
+
return (array) => {
|
|
37
|
+
const withItems = createConcat(array, [item])([]);
|
|
38
|
+
return createReorder(
|
|
39
|
+
{ start: array.length, itemCount: 1 },
|
|
40
|
+
index
|
|
41
|
+
)(withItems);
|
|
46
42
|
};
|
|
47
43
|
}
|
|
44
|
+
function createMap(transform) {
|
|
45
|
+
return (array) => pipe(
|
|
46
|
+
map(transform),
|
|
47
|
+
toArray()
|
|
48
|
+
)(array);
|
|
49
|
+
}
|
|
50
|
+
function createReduce(accumulate, initialValue) {
|
|
51
|
+
return (array) => reduce(accumulate, initialValue)(array);
|
|
52
|
+
}
|
|
48
53
|
function createRemove(index) {
|
|
49
54
|
return (array) => {
|
|
50
55
|
return createConcat(
|
|
@@ -53,15 +58,6 @@ function createRemove(index) {
|
|
|
53
58
|
)([]);
|
|
54
59
|
};
|
|
55
60
|
}
|
|
56
|
-
function createInsert(item, index) {
|
|
57
|
-
return (array) => {
|
|
58
|
-
const withItems = createConcat(array, [item])([]);
|
|
59
|
-
return createReorder(
|
|
60
|
-
{ start: array.length, itemCount: 1 },
|
|
61
|
-
index
|
|
62
|
-
)(withItems);
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
61
|
function createReorder(from, to) {
|
|
66
62
|
return (array) => {
|
|
67
63
|
const [itemsToMoveStartIndex, itemsToMoveCount] = predicateObject(from) ? [from.start, from.itemCount] : [from, 1], insertIndex = to;
|
|
@@ -90,8 +86,34 @@ function createReorder(from, to) {
|
|
|
90
86
|
return array;
|
|
91
87
|
};
|
|
92
88
|
}
|
|
93
|
-
function
|
|
94
|
-
return
|
|
89
|
+
function createReplace(index, replacement) {
|
|
90
|
+
return createMap((item, i) => i === index ? replacement : item);
|
|
91
|
+
}
|
|
92
|
+
function createReverse() {
|
|
93
|
+
return (array) => {
|
|
94
|
+
const reversed = [];
|
|
95
|
+
for (let i = array.length - 1; i > -1; i--) {
|
|
96
|
+
reversed.push(array[i]);
|
|
97
|
+
}
|
|
98
|
+
return reversed;
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
function createSlice(from, to) {
|
|
102
|
+
const toSliced = to ? slice(from, to - 1) : slice(from);
|
|
103
|
+
return (array) => {
|
|
104
|
+
return from === to ? [] : pipe(
|
|
105
|
+
toSliced,
|
|
106
|
+
toArray()
|
|
107
|
+
)(array);
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
function createSort(compare) {
|
|
111
|
+
return (array) => {
|
|
112
|
+
return pipe(
|
|
113
|
+
sort(compare),
|
|
114
|
+
toArray()
|
|
115
|
+
)(array);
|
|
116
|
+
};
|
|
95
117
|
}
|
|
96
118
|
function createSwap(indices) {
|
|
97
119
|
return (array) => {
|
|
@@ -113,16 +135,7 @@ function createSwap(indices) {
|
|
|
113
135
|
reorderTo: (array2) => array2
|
|
114
136
|
};
|
|
115
137
|
})();
|
|
116
|
-
return
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
function createReplace(index, item) {
|
|
120
|
-
return (array) => {
|
|
121
|
-
return createConcat(
|
|
122
|
-
createSlice(0, index)(array),
|
|
123
|
-
[item],
|
|
124
|
-
createSlice(index + 1)(array)
|
|
125
|
-
)([]);
|
|
138
|
+
return pipe(reorderFrom, reorderTo)(array);
|
|
126
139
|
};
|
|
127
140
|
}
|
|
128
141
|
function createUnique() {
|
|
@@ -131,277 +144,1990 @@ function createUnique() {
|
|
|
131
144
|
toArray()
|
|
132
145
|
)(array);
|
|
133
146
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
147
|
+
|
|
148
|
+
function createFilterAsync(predicate) {
|
|
149
|
+
return async (array) => {
|
|
150
|
+
const transformedAsync = await createMapAsync(predicate)(array);
|
|
151
|
+
return createFilter((_, index) => transformedAsync[index])(array);
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
function createFindAsync(predicate) {
|
|
155
|
+
return async (array) => {
|
|
156
|
+
for (let i = 0; i < array.length; i++) {
|
|
157
|
+
const item = array[i], is = await predicate(item, i);
|
|
158
|
+
if (is)
|
|
159
|
+
return item;
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function createFindIndexAsync(predicate) {
|
|
164
|
+
return async (array) => {
|
|
165
|
+
for (let i = 0; i < array.length; i++) {
|
|
166
|
+
const item = array[i], is = await predicate(item, i);
|
|
167
|
+
if (is)
|
|
168
|
+
return i;
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
function createForEachAsync(forEach) {
|
|
173
|
+
return async (array) => {
|
|
174
|
+
for (let i = 0; i < array.length; i++) {
|
|
175
|
+
const item = array[i];
|
|
176
|
+
await forEach(item, i);
|
|
177
|
+
}
|
|
178
|
+
return array;
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
function createMapAsync(transform) {
|
|
182
|
+
return async (array) => {
|
|
183
|
+
return await createReduceAsync(
|
|
184
|
+
async (resolvedMaps, item, index) => {
|
|
185
|
+
const transformed = await transform(item, index);
|
|
186
|
+
resolvedMaps.push(transformed);
|
|
187
|
+
return resolvedMaps;
|
|
188
|
+
},
|
|
189
|
+
[]
|
|
139
190
|
)(array);
|
|
140
191
|
};
|
|
141
192
|
}
|
|
142
|
-
function
|
|
143
|
-
return (array) =>
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
193
|
+
function createReduceAsync(accumulate, initialValue) {
|
|
194
|
+
return async (array) => {
|
|
195
|
+
return await reduce(
|
|
196
|
+
async (accumulatorPromise, item, index) => {
|
|
197
|
+
const accumulator = await accumulatorPromise;
|
|
198
|
+
return accumulate(accumulator, item, index);
|
|
199
|
+
},
|
|
200
|
+
Promise.resolve(initialValue)
|
|
201
|
+
)(array);
|
|
202
|
+
};
|
|
147
203
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
204
|
+
|
|
205
|
+
function createClip(required) {
|
|
206
|
+
return (string) => {
|
|
207
|
+
return string.replace(required, "");
|
|
208
|
+
};
|
|
153
209
|
}
|
|
154
|
-
function
|
|
155
|
-
return (
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
)();
|
|
210
|
+
function createSlug(options) {
|
|
211
|
+
return (string) => {
|
|
212
|
+
return slugify(string, options);
|
|
213
|
+
};
|
|
159
214
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
215
|
+
|
|
216
|
+
function createClamp(min, max) {
|
|
217
|
+
return (number) => {
|
|
218
|
+
const maxed = Math.max(number, min);
|
|
219
|
+
return Math.min(maxed, max);
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
function createDetermine(potentialities) {
|
|
223
|
+
const predicates = createMap(({ outcome, probability }, index) => {
|
|
224
|
+
const lowerBound = index === 0 ? 0 : pipe(
|
|
225
|
+
slice(0, index - 1),
|
|
226
|
+
reduce((lowerBound2, { probability: probability2 }) => lowerBound2 + probability2, 0)
|
|
227
|
+
)(potentialities), upperBound = lowerBound + probability;
|
|
228
|
+
return {
|
|
229
|
+
outcome,
|
|
230
|
+
predicate: (determinant) => determinant >= lowerBound && determinant < upperBound || determinant < 0 && index === 0 || index === predicates.length - 1
|
|
231
|
+
};
|
|
232
|
+
})(potentialities);
|
|
233
|
+
return (determinant) => find(({ predicate }) => predicate(determinant))(predicates).outcome;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function createEntries() {
|
|
237
|
+
return (object) => {
|
|
238
|
+
const entries = [];
|
|
239
|
+
for (const key in object) {
|
|
240
|
+
entries.push([key, object[key]]);
|
|
241
|
+
}
|
|
242
|
+
return entries;
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
function createKeys() {
|
|
246
|
+
return (object) => {
|
|
247
|
+
const keys = [];
|
|
248
|
+
for (const key in object) {
|
|
249
|
+
keys.push(key);
|
|
250
|
+
}
|
|
251
|
+
return keys;
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
function createEvery(predicate) {
|
|
255
|
+
return (object) => {
|
|
256
|
+
for (const key in object) {
|
|
257
|
+
if (!predicate(key, object[key])) {
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return true;
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
function createSome(predicate) {
|
|
265
|
+
return (object) => {
|
|
266
|
+
for (const key in object) {
|
|
267
|
+
if (predicate(key, object[key]))
|
|
268
|
+
return true;
|
|
269
|
+
}
|
|
270
|
+
return false;
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
function createRename(from, to) {
|
|
275
|
+
return (map) => {
|
|
276
|
+
const keys = [...map.keys()], keyToRenameIndex = findIndex((k) => k === from)(keys), newKeys = createReplace(keyToRenameIndex, to)(keys), values = [...map.values()];
|
|
277
|
+
return createReduce((renamed, key, index) => renamed.set(key, values[index]), /* @__PURE__ */ new Map())(newKeys);
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const defaultOptions$m = {
|
|
282
|
+
elementIsCandidate: false,
|
|
283
|
+
// Adapted from React Aria https://github.com/adobe/react-spectrum/blob/b6786da906973130a1746b2bee63215bba013ca4/packages/%40react-aria/focus/src/FocusScope.tsx#L256
|
|
284
|
+
tabbableSelector: join(':not([hidden]):not([tabindex="-1"]),')([
|
|
285
|
+
"input:not([disabled]):not([type=hidden])",
|
|
286
|
+
"select:not([disabled])",
|
|
287
|
+
"textarea:not([disabled])",
|
|
288
|
+
"button:not([disabled])",
|
|
289
|
+
"a[href]",
|
|
290
|
+
"area[href]",
|
|
291
|
+
"summary",
|
|
292
|
+
"iframe",
|
|
293
|
+
"object",
|
|
294
|
+
"embed",
|
|
295
|
+
"audio[controls]",
|
|
296
|
+
"video[controls]",
|
|
297
|
+
"[contenteditable]",
|
|
298
|
+
"[tabindex]:not([disabled])"
|
|
299
|
+
])
|
|
300
|
+
};
|
|
301
|
+
function createFocusable(order, options = {}) {
|
|
302
|
+
const { elementIsCandidate, tabbableSelector } = { ...defaultOptions$m, ...options }, predicateFocusable = (element) => element.matches(tabbableSelector);
|
|
303
|
+
return (element) => {
|
|
304
|
+
if (elementIsCandidate && predicateFocusable(element))
|
|
305
|
+
return element;
|
|
306
|
+
switch (order) {
|
|
307
|
+
case "first":
|
|
308
|
+
for (let i = 0; i < element.children.length; i++) {
|
|
309
|
+
const focusable = createFocusable(order, { elementIsCandidate: true })(element.children[i]);
|
|
310
|
+
if (focusable)
|
|
311
|
+
return focusable;
|
|
312
|
+
}
|
|
313
|
+
break;
|
|
314
|
+
case "last":
|
|
315
|
+
for (let i = element.children.length - 1; i > -1; i--) {
|
|
316
|
+
const focusable = createFocusable(order, { elementIsCandidate: true })(element.children[i]);
|
|
317
|
+
if (focusable)
|
|
318
|
+
return focusable;
|
|
319
|
+
}
|
|
320
|
+
break;
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
function createToIndegree(graph) {
|
|
326
|
+
const toIncoming = createToIncoming(graph);
|
|
327
|
+
return (node) => pipe(
|
|
328
|
+
toIncoming,
|
|
329
|
+
toLength()
|
|
330
|
+
)(node);
|
|
331
|
+
}
|
|
332
|
+
function createToOutdegree(graph) {
|
|
333
|
+
const toOutgoing = createToOutgoing(graph);
|
|
334
|
+
return (node) => pipe(
|
|
335
|
+
toOutgoing,
|
|
336
|
+
toLength()
|
|
337
|
+
)(node);
|
|
338
|
+
}
|
|
339
|
+
function createToIncoming(graph) {
|
|
340
|
+
const { edges } = graph;
|
|
341
|
+
return function* (node) {
|
|
342
|
+
yield* filter(
|
|
343
|
+
({ to }) => to === node
|
|
344
|
+
)(edges);
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
function createToOutgoing(graph) {
|
|
348
|
+
const { edges } = graph;
|
|
349
|
+
return function* (node) {
|
|
350
|
+
yield* filter(
|
|
351
|
+
({ from }) => from === node
|
|
352
|
+
)(edges);
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
function createPredicateRoot(graph) {
|
|
356
|
+
const toIndegree = createToIndegree(graph);
|
|
357
|
+
return (node) => toIndegree(node) === 0;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
function createFind(node) {
|
|
361
|
+
return (tree) => {
|
|
362
|
+
for (const treeNode of tree) {
|
|
363
|
+
if (treeNode.node === node)
|
|
364
|
+
return treeNode;
|
|
365
|
+
const found = createFind(node)(treeNode.children);
|
|
366
|
+
if (found)
|
|
367
|
+
return found;
|
|
368
|
+
}
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
function createToLayers$1(options = {}) {
|
|
373
|
+
const toSteps = createToSteps$2(options.createToSteps);
|
|
374
|
+
return function toLayers(directedAcyclic) {
|
|
375
|
+
const layers = [];
|
|
376
|
+
for (const { path } of toSteps(directedAcyclic)) {
|
|
377
|
+
const node = path.at(-1), depth = path.length - 1;
|
|
378
|
+
(layers[depth] || (layers[depth] = [])).push(node);
|
|
379
|
+
}
|
|
380
|
+
return layers;
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
function createToTree$2(options = {}) {
|
|
384
|
+
const toSteps = createToSteps$2(options.createToSteps);
|
|
385
|
+
return function toTree(directedAcyclic) {
|
|
386
|
+
const firstRoot = pipe(
|
|
387
|
+
createToRoots(),
|
|
388
|
+
at(0)
|
|
389
|
+
)(directedAcyclic), tree = [];
|
|
390
|
+
tree.push({
|
|
391
|
+
node: firstRoot,
|
|
392
|
+
children: []
|
|
393
|
+
});
|
|
394
|
+
for (const { path } of toSteps(directedAcyclic)) {
|
|
395
|
+
const node = path.at(-1), parent = path.at(-2);
|
|
396
|
+
if (parent) {
|
|
397
|
+
const parentTreeNode = createFind(parent)(tree);
|
|
398
|
+
if (parentTreeNode) {
|
|
399
|
+
parentTreeNode.children.push({
|
|
400
|
+
node,
|
|
401
|
+
children: []
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
return tree;
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
function createToCommonAncestors$2(directedAcyclic) {
|
|
410
|
+
const toNodeSteps = createToNodeSteps$2(directedAcyclic);
|
|
411
|
+
return function* (a, b) {
|
|
412
|
+
for (const { path: aPath } of toNodeSteps(a)) {
|
|
413
|
+
for (const { path: bPath } of toNodeSteps(b)) {
|
|
414
|
+
for (let aPathIndex = aPath.length - 1; aPathIndex >= 0; aPathIndex--) {
|
|
415
|
+
for (let bPathIndex = bPath.length - 1; bPathIndex >= 0; bPathIndex--) {
|
|
416
|
+
if (aPath[aPathIndex] === bPath[bPathIndex] && !includes(aPath[aPathIndex])([a, b])) {
|
|
417
|
+
yield {
|
|
418
|
+
node: aPath[aPathIndex],
|
|
419
|
+
distances: {
|
|
420
|
+
[a]: aPath.length - aPathIndex - 1,
|
|
421
|
+
[b]: bPath.length - bPathIndex - 1
|
|
422
|
+
}
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
function createPredicateAncestor$2(directedAcyclic) {
|
|
432
|
+
const toNodeSteps = createToNodeSteps$2(directedAcyclic);
|
|
433
|
+
return function(descendant, ancestor) {
|
|
434
|
+
return pipe(
|
|
435
|
+
toNodeSteps,
|
|
436
|
+
some(({ path }) => includes(ancestor)(path))
|
|
437
|
+
)(descendant);
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
function createToNodeSteps$2(directedAcyclic, options = {}) {
|
|
441
|
+
const toSteps = createToSteps$2(options.createToSteps);
|
|
442
|
+
return function* (node) {
|
|
443
|
+
yield* pipe(
|
|
444
|
+
toSteps,
|
|
445
|
+
filter(({ path }) => path.at(-1) === node)
|
|
446
|
+
)(directedAcyclic);
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
const defaultCreateToStepsOptions$1 = {
|
|
450
|
+
toUnsetMetadata: () => 0,
|
|
451
|
+
toMockMetadata: (node, totalConnectionsFollowed) => totalConnectionsFollowed,
|
|
452
|
+
kind: "directed acyclic"
|
|
453
|
+
};
|
|
454
|
+
function createToSteps$2(options = {}) {
|
|
455
|
+
const { toUnsetMetadata, toMockMetadata, root, kind } = { ...defaultCreateToStepsOptions$1, ...options };
|
|
456
|
+
return function* (directedAcyclic) {
|
|
457
|
+
const { nodes } = directedAcyclic, toOutdegree = createToOutdegree(directedAcyclic), toPath = createToPath$2(directedAcyclic), roots = pipe(
|
|
458
|
+
createToRoots({ kind }),
|
|
459
|
+
toArray()
|
|
460
|
+
)(directedAcyclic), state = {}, totalConnectionsFollowedByNode = {}, predicateExhausted = (node) => {
|
|
461
|
+
return totalConnectionsFollowedByNode[node] === toOutdegree(node);
|
|
462
|
+
};
|
|
463
|
+
for (const node of nodes) {
|
|
464
|
+
state[node] = {
|
|
465
|
+
status: "unset",
|
|
466
|
+
metadata: toUnsetMetadata(node)
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
let location = root || at(0)(roots);
|
|
470
|
+
const path = toPath(state);
|
|
471
|
+
yield { path, state: JSON.parse(JSON.stringify(state)) };
|
|
472
|
+
function* toStep() {
|
|
473
|
+
if (predicateExhausted(location)) {
|
|
474
|
+
if (includes(location)(roots))
|
|
475
|
+
return;
|
|
476
|
+
state[location].status = "unset";
|
|
477
|
+
state[location].metadata = toUnsetMetadata(location);
|
|
478
|
+
const path3 = toPath(state);
|
|
479
|
+
location = path3.at(-2);
|
|
480
|
+
yield* toStep();
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
if (!(location in totalConnectionsFollowedByNode))
|
|
484
|
+
totalConnectionsFollowedByNode[location] = 0;
|
|
485
|
+
state[location].status = "set";
|
|
486
|
+
state[location].metadata = toMockMetadata(location, totalConnectionsFollowedByNode[location]);
|
|
487
|
+
const path2 = toPath(state);
|
|
488
|
+
yield { path: path2, state: JSON.parse(JSON.stringify(state)) };
|
|
489
|
+
totalConnectionsFollowedByNode[location]++;
|
|
490
|
+
const newLocation = path2.at(-1);
|
|
491
|
+
if (toOutdegree(newLocation) > 0)
|
|
492
|
+
location = newLocation;
|
|
493
|
+
yield* toStep();
|
|
494
|
+
}
|
|
495
|
+
yield* toStep();
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
function createToPath$2(directedAcyclic) {
|
|
499
|
+
const toOutdegree = createToOutdegree(directedAcyclic), toOutgoing = createToOutgoing(directedAcyclic), firstRoot = pipe(
|
|
500
|
+
createToRoots(),
|
|
501
|
+
at(0)
|
|
502
|
+
)(directedAcyclic);
|
|
503
|
+
return (state) => {
|
|
504
|
+
const path = [firstRoot], getLastOutdegree = () => toOutdegree(path.at(-1)), getLastStatus = () => state[path.at(-1)].status;
|
|
505
|
+
while (getLastOutdegree() > 0 && getLastStatus() === "set") {
|
|
506
|
+
const edge = pipe(
|
|
507
|
+
toOutgoing,
|
|
508
|
+
find(
|
|
509
|
+
({ predicateTraversable }) => predicateTraversable(state)
|
|
510
|
+
)
|
|
511
|
+
)(path.at(-1));
|
|
512
|
+
path.push(edge.to);
|
|
513
|
+
}
|
|
514
|
+
return path;
|
|
515
|
+
};
|
|
516
|
+
}
|
|
517
|
+
function createToRoots(options = {}) {
|
|
518
|
+
return function* (directedAcyclic) {
|
|
519
|
+
const { nodes } = directedAcyclic;
|
|
520
|
+
for (const node of nodes) {
|
|
521
|
+
if (createPredicateRoot(directedAcyclic)(node))
|
|
522
|
+
yield node;
|
|
523
|
+
if (options.kind === "arborescence")
|
|
524
|
+
break;
|
|
525
|
+
}
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
function createToLayers(options = {}) {
|
|
530
|
+
const toSteps = createToSteps$1(options.createToSteps);
|
|
531
|
+
return async function toLayers(directedAcyclic) {
|
|
532
|
+
const layers = [];
|
|
533
|
+
for await (const { path } of toSteps(directedAcyclic)) {
|
|
534
|
+
const node = path.at(-1), depth = path.length - 1;
|
|
535
|
+
(layers[depth] || (layers[depth] = [])).push(node);
|
|
536
|
+
}
|
|
537
|
+
return layers;
|
|
538
|
+
};
|
|
539
|
+
}
|
|
540
|
+
function createToTree$1(options = {}) {
|
|
541
|
+
const toSteps = createToSteps$1(options.createToSteps);
|
|
542
|
+
return async function toTree(directedAcyclic) {
|
|
543
|
+
const firstRoot = pipe(
|
|
544
|
+
createToRoots(),
|
|
545
|
+
at(0)
|
|
546
|
+
)(directedAcyclic), tree = [];
|
|
547
|
+
tree.push({
|
|
548
|
+
node: firstRoot,
|
|
549
|
+
children: []
|
|
550
|
+
});
|
|
551
|
+
for await (const { path } of toSteps(directedAcyclic)) {
|
|
552
|
+
const node = path.at(-1), parent = path.at(-2);
|
|
553
|
+
if (parent) {
|
|
554
|
+
const parentTreeNode = createFind(parent)(tree);
|
|
555
|
+
if (parentTreeNode) {
|
|
556
|
+
parentTreeNode.children.push({
|
|
557
|
+
node,
|
|
558
|
+
children: []
|
|
559
|
+
});
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
return tree;
|
|
564
|
+
};
|
|
565
|
+
}
|
|
566
|
+
function createToCommonAncestors$1(directedAcyclic) {
|
|
567
|
+
const toNodeSteps = createToNodeSteps$1(directedAcyclic);
|
|
568
|
+
return async function* (a, b) {
|
|
569
|
+
for await (const { path: aPath } of toNodeSteps(a)) {
|
|
570
|
+
for await (const { path: bPath } of toNodeSteps(b)) {
|
|
571
|
+
for (let aPathIndex = aPath.length - 1; aPathIndex >= 0; aPathIndex--) {
|
|
572
|
+
for (let bPathIndex = bPath.length - 1; bPathIndex >= 0; bPathIndex--) {
|
|
573
|
+
if (aPath[aPathIndex] === bPath[bPathIndex] && !includes(aPath[aPathIndex])([a, b])) {
|
|
574
|
+
yield {
|
|
575
|
+
node: aPath[aPathIndex],
|
|
576
|
+
distances: {
|
|
577
|
+
[a]: aPath.length - aPathIndex - 1,
|
|
578
|
+
[b]: bPath.length - bPathIndex - 1
|
|
579
|
+
}
|
|
580
|
+
};
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
};
|
|
587
|
+
}
|
|
588
|
+
function createPredicateAncestor$1(directedAcyclic) {
|
|
589
|
+
const toNodeSteps = createToNodeSteps$1(directedAcyclic);
|
|
590
|
+
return async function(descendant, ancestor) {
|
|
591
|
+
return await pipe(
|
|
592
|
+
toNodeSteps,
|
|
593
|
+
some(({ path }) => includes(ancestor)(path))
|
|
594
|
+
)(descendant);
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
function createToNodeSteps$1(directedAcyclic, options = {}) {
|
|
598
|
+
const toSteps = createToSteps$1(options.createToSteps);
|
|
599
|
+
return async function* (node) {
|
|
600
|
+
yield* await pipe(
|
|
601
|
+
toSteps,
|
|
602
|
+
filter(({ path }) => path.at(-1) === node)
|
|
603
|
+
)(directedAcyclic);
|
|
604
|
+
};
|
|
605
|
+
}
|
|
606
|
+
function createToSteps$1(options = {}) {
|
|
607
|
+
const { toUnsetMetadata, toMockMetadata, root, kind } = { ...defaultCreateToStepsOptions$1, ...options };
|
|
608
|
+
return async function* (directedAcyclic) {
|
|
609
|
+
const { nodes } = directedAcyclic, toOutdegree = createToOutdegree(directedAcyclic), toPath = createToPath$1(directedAcyclic), roots = pipe(
|
|
610
|
+
createToRoots({ kind }),
|
|
611
|
+
toArray()
|
|
612
|
+
)(directedAcyclic), state = {}, totalConnectionsFollowedByNode = {}, predicateExhausted = (node) => {
|
|
613
|
+
return totalConnectionsFollowedByNode[node] === toOutdegree(node);
|
|
614
|
+
};
|
|
615
|
+
for (const node of nodes) {
|
|
616
|
+
state[node] = {
|
|
617
|
+
status: "unset",
|
|
618
|
+
metadata: toUnsetMetadata(node)
|
|
619
|
+
};
|
|
620
|
+
}
|
|
621
|
+
let location = root || at(0)(roots);
|
|
622
|
+
const path = await toPath(state);
|
|
623
|
+
yield { path, state: JSON.parse(JSON.stringify(state)) };
|
|
624
|
+
async function* toStep() {
|
|
625
|
+
if (predicateExhausted(location)) {
|
|
626
|
+
if (includes(location)(roots))
|
|
627
|
+
return;
|
|
628
|
+
state[location].status = "unset";
|
|
629
|
+
state[location].metadata = toUnsetMetadata(location);
|
|
630
|
+
const path3 = await toPath(state);
|
|
631
|
+
location = path3.at(-2);
|
|
632
|
+
yield* await toStep();
|
|
633
|
+
return;
|
|
634
|
+
}
|
|
635
|
+
if (!(location in totalConnectionsFollowedByNode))
|
|
636
|
+
totalConnectionsFollowedByNode[location] = 0;
|
|
637
|
+
state[location].status = "set";
|
|
638
|
+
state[location].metadata = toMockMetadata(location, totalConnectionsFollowedByNode[location]);
|
|
639
|
+
const path2 = await toPath(state);
|
|
640
|
+
yield { path: path2, state: JSON.parse(JSON.stringify(state)) };
|
|
641
|
+
totalConnectionsFollowedByNode[location]++;
|
|
642
|
+
const newLocation = path2.at(-1);
|
|
643
|
+
if (toOutdegree(newLocation) > 0)
|
|
644
|
+
location = newLocation;
|
|
645
|
+
yield* await toStep();
|
|
646
|
+
}
|
|
647
|
+
yield* await toStep();
|
|
648
|
+
};
|
|
649
|
+
}
|
|
650
|
+
function createToPath$1(directedAcyclic) {
|
|
651
|
+
const toOutdegree = createToOutdegree(directedAcyclic), toOutgoing = createToOutgoing(directedAcyclic), firstRoot = pipe(
|
|
652
|
+
createToRoots(),
|
|
653
|
+
at(0)
|
|
654
|
+
)(directedAcyclic);
|
|
655
|
+
return async (state) => {
|
|
656
|
+
const path = [firstRoot], getLastOutdegree = () => toOutdegree(path.at(-1)), getLastStatus = () => state[path.at(-1)].status;
|
|
657
|
+
while (getLastOutdegree() > 0 && getLastStatus() === "set") {
|
|
658
|
+
const edge = await pipe(
|
|
659
|
+
toOutgoing,
|
|
660
|
+
toArray(),
|
|
661
|
+
createFindAsync(
|
|
662
|
+
async ({ predicateTraversable }) => await predicateTraversable(state)
|
|
663
|
+
)
|
|
664
|
+
)(path.at(-1));
|
|
665
|
+
path.push(edge.to);
|
|
666
|
+
}
|
|
667
|
+
return path;
|
|
668
|
+
};
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
const defaultCreateToStepsOptions = {
|
|
672
|
+
priorityBranch: false,
|
|
673
|
+
kind: "directed acyclic"
|
|
674
|
+
};
|
|
675
|
+
function createToTree(options = {}) {
|
|
676
|
+
const withDefaults = {
|
|
677
|
+
...options,
|
|
678
|
+
createToSteps: {
|
|
679
|
+
...defaultCreateToStepsOptions,
|
|
680
|
+
...options.createToSteps
|
|
681
|
+
}
|
|
682
|
+
};
|
|
683
|
+
return createToTree$2({
|
|
684
|
+
...withDefaults,
|
|
685
|
+
createToSteps: toCreateDirectedAcyclicToStepsOptions(withDefaults.createToSteps)
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
function createToCommonAncestors(...params) {
|
|
689
|
+
return createToCommonAncestors$2(...params);
|
|
690
|
+
}
|
|
691
|
+
function createPredicateAncestor(...params) {
|
|
692
|
+
return createPredicateAncestor$2(...params);
|
|
693
|
+
}
|
|
694
|
+
function createToNodeSteps(decisionTree, options = {}) {
|
|
695
|
+
const withDefaults = {
|
|
696
|
+
...options,
|
|
697
|
+
createToSteps: {
|
|
698
|
+
...defaultCreateToStepsOptions,
|
|
699
|
+
...options.createToSteps
|
|
700
|
+
}
|
|
701
|
+
};
|
|
702
|
+
return createToNodeSteps$2(
|
|
703
|
+
decisionTree,
|
|
704
|
+
{
|
|
705
|
+
...withDefaults,
|
|
706
|
+
createToSteps: toCreateDirectedAcyclicToStepsOptions(withDefaults.createToSteps)
|
|
707
|
+
}
|
|
708
|
+
);
|
|
709
|
+
}
|
|
710
|
+
function createToSteps(options = {}) {
|
|
711
|
+
const withDefaults = {
|
|
712
|
+
...defaultCreateToStepsOptions,
|
|
713
|
+
...options
|
|
714
|
+
};
|
|
715
|
+
return createToSteps$2(
|
|
716
|
+
toCreateDirectedAcyclicToStepsOptions(withDefaults)
|
|
717
|
+
);
|
|
718
|
+
}
|
|
719
|
+
function createToPath(...params) {
|
|
720
|
+
return createToPath$2(...params);
|
|
721
|
+
}
|
|
722
|
+
function toCreateDirectedAcyclicToStepsOptions(options) {
|
|
723
|
+
return {
|
|
724
|
+
...defaultCreateToStepsOptions,
|
|
725
|
+
...options,
|
|
726
|
+
...{
|
|
727
|
+
toUnsetMetadata: () => false,
|
|
728
|
+
toMockMetadata: (node, totalConnectionsFollowed) => options.priorityBranch ? !totalConnectionsFollowed : !!totalConnectionsFollowed
|
|
729
|
+
}
|
|
730
|
+
};
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
function createList() {
|
|
734
|
+
return (...classValues) => clsx(...classValues);
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
const defaultOptions$l = {
|
|
738
|
+
toId: (node) => node.id,
|
|
739
|
+
toChildren: (node) => node.children
|
|
740
|
+
};
|
|
741
|
+
function createToGraph(options = {}) {
|
|
742
|
+
const { toId, toChildren } = { ...defaultOptions$l, ...options };
|
|
743
|
+
return function* (tree) {
|
|
744
|
+
const root = tree[0], rootId = toId(root);
|
|
745
|
+
function* toPair(node, id) {
|
|
746
|
+
const children = toChildren(node) || [];
|
|
747
|
+
for (const child of children) {
|
|
748
|
+
const childId = toId(child);
|
|
749
|
+
yield {
|
|
750
|
+
node: childId,
|
|
751
|
+
edge: { from: id, to: childId }
|
|
752
|
+
};
|
|
753
|
+
yield* toPair(child, childId);
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
yield { node: rootId };
|
|
757
|
+
yield* toPair(root, rootId);
|
|
758
|
+
};
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
const defaultOptions$k = {
|
|
762
|
+
toKey: (alias) => fromAliasToKeyStatusKey(alias)
|
|
763
|
+
};
|
|
764
|
+
const createPredicateKeycomboMatch$1 = (keycombo, options = {}) => {
|
|
765
|
+
const { toKey } = { ...defaultOptions$k, ...options }, keys = pipe(
|
|
766
|
+
fromComboToAliases,
|
|
767
|
+
map(toKey)
|
|
768
|
+
)(keycombo);
|
|
769
|
+
return (event) => {
|
|
770
|
+
const { toValue, set } = createKeyStatuses();
|
|
771
|
+
set(fromEventToKeyStatusKey(event), "down");
|
|
772
|
+
for (const modifier of modifiers) {
|
|
773
|
+
if (event[`${modifier.toLowerCase()}Key`])
|
|
774
|
+
set({ key: modifier }, "down");
|
|
775
|
+
}
|
|
776
|
+
return every(pipe(
|
|
777
|
+
toValue,
|
|
778
|
+
predicateDown
|
|
779
|
+
))(keys);
|
|
780
|
+
};
|
|
781
|
+
};
|
|
782
|
+
|
|
783
|
+
const defaultOptions$j = {
|
|
784
|
+
initial: [],
|
|
785
|
+
createPredicateKey: (query) => (candidate) => query === candidate
|
|
786
|
+
};
|
|
787
|
+
function createAssociativeArray(options = {}) {
|
|
788
|
+
const { initial, createPredicateKey } = { ...defaultOptions$j, ...options }, entries = [...initial];
|
|
789
|
+
const toValue = (key) => {
|
|
790
|
+
const predicateKey = createPredicateKey(key);
|
|
791
|
+
return find(
|
|
792
|
+
([candidate]) => predicateKey(candidate)
|
|
793
|
+
)(entries)?.[1];
|
|
794
|
+
};
|
|
795
|
+
const set = (key, value) => {
|
|
796
|
+
const predicateKey = createPredicateKey(key), index = findIndex(
|
|
797
|
+
([candidate]) => predicateKey(candidate)
|
|
798
|
+
)(entries);
|
|
799
|
+
if (index === -1) {
|
|
800
|
+
entries.push([key, value]);
|
|
801
|
+
return;
|
|
802
|
+
}
|
|
803
|
+
entries[index][1] = value;
|
|
804
|
+
};
|
|
805
|
+
const predicateHas = (key) => {
|
|
806
|
+
const predicateKey = createPredicateKey(key);
|
|
807
|
+
return findIndex(
|
|
808
|
+
([candidate]) => predicateKey(candidate)
|
|
809
|
+
)(entries) !== -1;
|
|
810
|
+
};
|
|
811
|
+
const clear = () => {
|
|
812
|
+
entries.length = 0;
|
|
813
|
+
};
|
|
814
|
+
const del = (key) => {
|
|
815
|
+
const predicateKey = createPredicateKey(key), index = findIndex(
|
|
816
|
+
([candidate]) => predicateKey(candidate)
|
|
817
|
+
)(entries);
|
|
818
|
+
if (index === -1) {
|
|
819
|
+
return false;
|
|
820
|
+
}
|
|
821
|
+
entries.splice(index, 1);
|
|
822
|
+
return true;
|
|
823
|
+
};
|
|
824
|
+
const toKeys = () => {
|
|
825
|
+
return createMap(([key]) => key)(entries);
|
|
826
|
+
};
|
|
827
|
+
const toValues = () => {
|
|
828
|
+
return createMap(([, value]) => value)(entries);
|
|
829
|
+
};
|
|
830
|
+
const toEntries = () => {
|
|
831
|
+
return entries;
|
|
832
|
+
};
|
|
833
|
+
return {
|
|
834
|
+
toValue,
|
|
835
|
+
set,
|
|
836
|
+
predicateHas,
|
|
837
|
+
clear,
|
|
838
|
+
delete: del,
|
|
839
|
+
toKeys,
|
|
840
|
+
toValues,
|
|
841
|
+
toEntries
|
|
842
|
+
// get: toValue,
|
|
843
|
+
// has: predicateHas,
|
|
844
|
+
// keys: toKeys,
|
|
845
|
+
// values: toValues,
|
|
846
|
+
};
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
const defaultOptions$i = {
|
|
850
|
+
minDuration: 0,
|
|
851
|
+
preventsDefaultUnlessDenied: true,
|
|
852
|
+
toKey: (alias) => fromAliasToKeyStatusKey(alias),
|
|
853
|
+
toAliases: (event) => fromEventToAliases(event)
|
|
854
|
+
};
|
|
855
|
+
function createKeypress(keycomboOrKeycombos, options = {}) {
|
|
856
|
+
const {
|
|
857
|
+
minDuration,
|
|
858
|
+
preventsDefaultUnlessDenied,
|
|
859
|
+
toKey,
|
|
860
|
+
toAliases,
|
|
861
|
+
onDown,
|
|
862
|
+
onUp,
|
|
863
|
+
onVisibilitychange
|
|
864
|
+
} = { ...defaultOptions$i, ...options }, {
|
|
865
|
+
matchPredicatesByKeycombo,
|
|
866
|
+
getDownCombos,
|
|
867
|
+
predicateValid,
|
|
868
|
+
cleanup,
|
|
869
|
+
statuses
|
|
870
|
+
} = createKeyState({
|
|
871
|
+
keycomboOrKeycombos,
|
|
872
|
+
unsupportedAliases: unsupportedAliases$2,
|
|
873
|
+
toKey,
|
|
874
|
+
toAliases,
|
|
875
|
+
getRequest: () => request
|
|
876
|
+
});
|
|
877
|
+
let request;
|
|
878
|
+
let localStatus;
|
|
879
|
+
const keydown = (event, api) => {
|
|
880
|
+
const { denied, getStatus } = api, key = fromEventToKeyStatusKey(event);
|
|
881
|
+
if (statuses.toValue(key) === "down") {
|
|
882
|
+
onDown?.(toHookApi(api));
|
|
883
|
+
return;
|
|
884
|
+
}
|
|
885
|
+
statuses.set(key, "down");
|
|
886
|
+
if (localStatus === "denied") {
|
|
887
|
+
denied();
|
|
888
|
+
onDown?.(toHookApi(api));
|
|
889
|
+
return;
|
|
890
|
+
}
|
|
891
|
+
const downCombos = getDownCombos();
|
|
892
|
+
if (
|
|
893
|
+
// NOT BUILDING VALID COMBO
|
|
894
|
+
!predicateValid(event) || downCombos.length > 1 && fromComboToAliasesLength(downCombos[0]) === fromComboToAliasesLength(downCombos[1])
|
|
895
|
+
) {
|
|
896
|
+
denied();
|
|
897
|
+
localStatus = getStatus();
|
|
898
|
+
if (includes(event.key)(unsupportedKeys$2))
|
|
899
|
+
statuses.clear();
|
|
900
|
+
onDown?.(toHookApi(api));
|
|
901
|
+
return;
|
|
902
|
+
}
|
|
903
|
+
if (preventsDefaultUnlessDenied)
|
|
904
|
+
event.preventDefault();
|
|
905
|
+
const { getMetadata } = api, metadata = getMetadata();
|
|
906
|
+
metadata.pressed = downCombos[0];
|
|
907
|
+
localStatus = "recognizing";
|
|
908
|
+
cleanup();
|
|
909
|
+
storeKeyboardTimeMetadata({
|
|
910
|
+
event,
|
|
911
|
+
api,
|
|
912
|
+
getTimeMetadata: getMetadata,
|
|
913
|
+
getShouldStore: () => downCombos.length && getDownCombos()[0] === downCombos[0],
|
|
914
|
+
setRequest: (newRequest) => request = newRequest,
|
|
915
|
+
recognize
|
|
916
|
+
});
|
|
917
|
+
onDown?.(toHookApi(api));
|
|
918
|
+
};
|
|
919
|
+
const recognize = (event, api) => {
|
|
920
|
+
const { getMetadata, recognized } = api, metadata = getMetadata();
|
|
921
|
+
if (metadata.duration >= minDuration) {
|
|
922
|
+
recognized();
|
|
923
|
+
localStatus = "recognized";
|
|
924
|
+
return;
|
|
925
|
+
}
|
|
926
|
+
};
|
|
927
|
+
const keyup = (event, api) => {
|
|
928
|
+
const { denied } = api, key = fromEventToKeyStatusKey(event);
|
|
929
|
+
if (localStatus === "denied") {
|
|
930
|
+
denied();
|
|
931
|
+
if (includes(event.key)(unsupportedKeys$2))
|
|
932
|
+
statuses.clear();
|
|
933
|
+
else
|
|
934
|
+
statuses.delete(key);
|
|
935
|
+
if (!predicateSomeKeyDown(statuses))
|
|
936
|
+
localStatus = "recognizing";
|
|
937
|
+
onUp?.(toHookApi(api));
|
|
938
|
+
return;
|
|
939
|
+
}
|
|
940
|
+
statuses.delete(key);
|
|
941
|
+
const downCombos = getDownCombos(), matches = matchPredicatesByKeycombo[downCombos[0]]?.(statuses);
|
|
942
|
+
if (downCombos.length && matches) {
|
|
943
|
+
const { getMetadata } = api, metadata = getMetadata();
|
|
944
|
+
metadata.pressed = downCombos[0];
|
|
945
|
+
if (preventsDefaultUnlessDenied)
|
|
946
|
+
event.preventDefault();
|
|
947
|
+
localStatus = "recognizing";
|
|
948
|
+
onUp?.(toHookApi(api));
|
|
949
|
+
return;
|
|
950
|
+
}
|
|
951
|
+
denied();
|
|
952
|
+
cleanup();
|
|
953
|
+
onUp?.(toHookApi(api));
|
|
954
|
+
};
|
|
955
|
+
const visibilitychange = (event, api) => {
|
|
956
|
+
if (document.visibilityState === "hidden") {
|
|
957
|
+
statuses.clear();
|
|
958
|
+
localStatus = "recognizing";
|
|
959
|
+
cleanup();
|
|
960
|
+
}
|
|
961
|
+
onVisibilitychange?.(toHookApi(api));
|
|
962
|
+
};
|
|
963
|
+
return {
|
|
964
|
+
keydown,
|
|
965
|
+
keyup,
|
|
966
|
+
visibilitychange
|
|
967
|
+
};
|
|
968
|
+
}
|
|
969
|
+
const unsupportedAliases$2 = ["meta", "command", "cmd"];
|
|
970
|
+
const unsupportedKeys$2 = ["Meta"];
|
|
971
|
+
|
|
972
|
+
const defaultOptions$h = {
|
|
973
|
+
minDuration: 0,
|
|
974
|
+
preventsDefaultUnlessDenied: true,
|
|
975
|
+
toKey: (alias) => fromAliasToKeyStatusKey(alias),
|
|
976
|
+
toAliases: (event) => fromEventToAliases(event)
|
|
977
|
+
};
|
|
978
|
+
function createKeyrelease(keycomboOrKeycombos, options = {}) {
|
|
979
|
+
const {
|
|
980
|
+
minDuration,
|
|
981
|
+
preventsDefaultUnlessDenied,
|
|
982
|
+
toKey,
|
|
983
|
+
toAliases,
|
|
984
|
+
onDown,
|
|
985
|
+
onUp,
|
|
986
|
+
onVisibilitychange
|
|
987
|
+
} = { ...defaultOptions$h, ...options }, {
|
|
988
|
+
matchPredicatesByKeycombo,
|
|
989
|
+
getDownCombos,
|
|
990
|
+
predicateValid,
|
|
991
|
+
cleanup,
|
|
992
|
+
statuses
|
|
993
|
+
} = createKeyState({
|
|
994
|
+
keycomboOrKeycombos,
|
|
995
|
+
unsupportedAliases: unsupportedAliases$1,
|
|
996
|
+
toKey,
|
|
997
|
+
toAliases,
|
|
998
|
+
getRequest: () => request
|
|
999
|
+
});
|
|
1000
|
+
let request, localStatus;
|
|
1001
|
+
const keydown = (event, api) => {
|
|
1002
|
+
const { denied, getStatus } = api, key = fromEventToKeyStatusKey(event);
|
|
1003
|
+
if (statuses.toValue(key) === "down") {
|
|
1004
|
+
onDown?.(toHookApi(api));
|
|
1005
|
+
return;
|
|
1006
|
+
}
|
|
1007
|
+
statuses.set(key, "down");
|
|
1008
|
+
if (localStatus === "denied") {
|
|
1009
|
+
denied();
|
|
1010
|
+
onDown?.(toHookApi(api));
|
|
1011
|
+
return;
|
|
1012
|
+
}
|
|
1013
|
+
const downCombos = getDownCombos();
|
|
1014
|
+
if (
|
|
1015
|
+
// NOT BUILDING VALID COMBO
|
|
1016
|
+
!predicateValid(event) || downCombos.length > 1 && fromComboToAliasesLength(downCombos[0]) === fromComboToAliasesLength(downCombos[1])
|
|
1017
|
+
) {
|
|
1018
|
+
denied();
|
|
1019
|
+
localStatus = getStatus();
|
|
1020
|
+
if (includes(event.key)(unsupportedKeys$1))
|
|
1021
|
+
statuses.clear();
|
|
1022
|
+
onDown?.(toHookApi(api));
|
|
1023
|
+
return;
|
|
1024
|
+
}
|
|
1025
|
+
if (preventsDefaultUnlessDenied)
|
|
1026
|
+
event.preventDefault();
|
|
1027
|
+
const { getMetadata } = api;
|
|
1028
|
+
localStatus = "recognizing";
|
|
1029
|
+
cleanup();
|
|
1030
|
+
storeKeyboardTimeMetadata({
|
|
1031
|
+
event,
|
|
1032
|
+
api,
|
|
1033
|
+
getTimeMetadata: getMetadata,
|
|
1034
|
+
getShouldStore: () => downCombos.length && getDownCombos()[0] === downCombos[0],
|
|
1035
|
+
setRequest: (newRequest) => request = newRequest
|
|
1036
|
+
});
|
|
1037
|
+
onDown?.(toHookApi(api));
|
|
1038
|
+
};
|
|
1039
|
+
const keyup = (event, api) => {
|
|
1040
|
+
const {
|
|
1041
|
+
getStatus,
|
|
1042
|
+
getMetadata,
|
|
1043
|
+
denied
|
|
1044
|
+
} = api, metadata = getMetadata(), key = fromEventToKeyStatusKey(event);
|
|
1045
|
+
if (["denied", "recognized"].includes(localStatus)) {
|
|
1046
|
+
if (localStatus === "denied")
|
|
1047
|
+
denied();
|
|
1048
|
+
if (includes(event.key)(unsupportedKeys$1))
|
|
1049
|
+
statuses.clear();
|
|
1050
|
+
else
|
|
1051
|
+
statuses.delete(key);
|
|
1052
|
+
if (!predicateSomeKeyDown(statuses))
|
|
1053
|
+
localStatus = "recognizing";
|
|
1054
|
+
onUp?.(toHookApi(api));
|
|
1055
|
+
return;
|
|
1056
|
+
}
|
|
1057
|
+
const downCombos = getDownCombos(), matches = matchPredicatesByKeycombo[downCombos[0]]?.(statuses);
|
|
1058
|
+
statuses.delete(key);
|
|
1059
|
+
if (!downCombos.length || !matches) {
|
|
1060
|
+
onUp?.(toHookApi(api));
|
|
1061
|
+
return;
|
|
1062
|
+
}
|
|
1063
|
+
recognize(event, api);
|
|
1064
|
+
const status = getStatus();
|
|
1065
|
+
if (status === "recognized") {
|
|
1066
|
+
localStatus = status;
|
|
1067
|
+
metadata.released = downCombos[0];
|
|
1068
|
+
}
|
|
1069
|
+
if (preventsDefaultUnlessDenied)
|
|
1070
|
+
event.preventDefault();
|
|
1071
|
+
onUp?.(toHookApi(api));
|
|
1072
|
+
};
|
|
1073
|
+
const recognize = (event, api) => {
|
|
1074
|
+
const { getMetadata, recognized, denied } = api, metadata = getMetadata();
|
|
1075
|
+
if (metadata.duration < minDuration) {
|
|
1076
|
+
denied();
|
|
1077
|
+
return;
|
|
1078
|
+
}
|
|
1079
|
+
recognized();
|
|
1080
|
+
};
|
|
1081
|
+
const visibilitychange = (event, api) => {
|
|
1082
|
+
if (document.visibilityState === "hidden") {
|
|
1083
|
+
statuses.clear();
|
|
1084
|
+
localStatus = "recognizing";
|
|
1085
|
+
cleanup();
|
|
1086
|
+
}
|
|
1087
|
+
onVisibilitychange?.(toHookApi(api));
|
|
1088
|
+
};
|
|
1089
|
+
return {
|
|
1090
|
+
keydown,
|
|
1091
|
+
keyup,
|
|
1092
|
+
visibilitychange
|
|
1093
|
+
};
|
|
1094
|
+
}
|
|
1095
|
+
const unsupportedAliases$1 = ["meta", "command", "cmd"];
|
|
1096
|
+
const unsupportedKeys$1 = ["Meta"];
|
|
1097
|
+
|
|
1098
|
+
const defaultOptions$g = {
|
|
1099
|
+
minDuration: 0,
|
|
1100
|
+
maxInterval: 5e3,
|
|
1101
|
+
// VS Code default
|
|
1102
|
+
preventsDefaultUnlessDenied: true,
|
|
1103
|
+
toKey: (alias) => fromAliasToKeyStatusKey(alias),
|
|
1104
|
+
toAliases: (event) => fromEventToAliases(event)
|
|
1105
|
+
};
|
|
1106
|
+
function createKeychord(keychord, options = {}) {
|
|
1107
|
+
const {
|
|
1108
|
+
minDuration,
|
|
1109
|
+
maxInterval,
|
|
1110
|
+
preventsDefaultUnlessDenied,
|
|
1111
|
+
toKey,
|
|
1112
|
+
toAliases,
|
|
1113
|
+
onDown,
|
|
1114
|
+
onUp,
|
|
1115
|
+
onVisibilitychange
|
|
1116
|
+
} = { ...defaultOptions$g, ...options }, narrowedKeychord = keychord.split(" "), keyStates = createMap((keycombo) => createKeyState({
|
|
1117
|
+
keycomboOrKeycombos: keycombo,
|
|
1118
|
+
unsupportedAliases,
|
|
1119
|
+
toKey,
|
|
1120
|
+
toAliases,
|
|
1121
|
+
getRequest: () => request
|
|
1122
|
+
}))(narrowedKeychord), localStatuses = createMap(
|
|
1123
|
+
() => "recognizing"
|
|
1124
|
+
)(keyStates);
|
|
1125
|
+
let request, playedIndex = 0;
|
|
1126
|
+
const keydown = (event, api) => {
|
|
1127
|
+
const { denied, getStatus } = api, key = fromEventToKeyStatusKey(event);
|
|
1128
|
+
if (keyStates[playedIndex].statuses.toValue(key) === "down") {
|
|
1129
|
+
onDown?.(toHookApi(api));
|
|
1130
|
+
return;
|
|
1131
|
+
}
|
|
1132
|
+
if (localStatuses[playedIndex] === "recognized") {
|
|
1133
|
+
playedIndex++;
|
|
1134
|
+
for (const [key2, status] of keyStates[playedIndex - 1].statuses.toEntries()) {
|
|
1135
|
+
keyStates[playedIndex].statuses.set(key2, status);
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
keyStates[playedIndex].statuses.set(key, "down");
|
|
1139
|
+
if (localStatuses[playedIndex] === "denied") {
|
|
1140
|
+
denied();
|
|
1141
|
+
onDown?.(toHookApi(api));
|
|
1142
|
+
return;
|
|
1143
|
+
}
|
|
1144
|
+
const { getMetadata } = api, metadata = getMetadata(), downCombos = keyStates[playedIndex].getDownCombos();
|
|
1145
|
+
if (playedIndex === 0)
|
|
1146
|
+
metadata.played = [];
|
|
1147
|
+
if (
|
|
1148
|
+
// NOT BUILDING VALID COMBO
|
|
1149
|
+
!keyStates[playedIndex].predicateValid(event) || downCombos.length > 1 && fromComboToAliasesLength(downCombos[0]) === fromComboToAliasesLength(downCombos[1]) || playedIndex > 0 && event.timeStamp - metadata.played[playedIndex - 1].times.end > maxInterval
|
|
1150
|
+
) {
|
|
1151
|
+
denied();
|
|
1152
|
+
localStatuses[playedIndex] = getStatus();
|
|
1153
|
+
if (includes(event.key)(unsupportedKeys)) {
|
|
1154
|
+
for (const { statuses } of keyStates)
|
|
1155
|
+
statuses.clear();
|
|
1156
|
+
}
|
|
1157
|
+
onDown?.(toHookApi(api));
|
|
1158
|
+
return;
|
|
1159
|
+
}
|
|
1160
|
+
if (preventsDefaultUnlessDenied)
|
|
1161
|
+
event.preventDefault();
|
|
1162
|
+
localStatuses[playedIndex] = "recognizing";
|
|
1163
|
+
keyStates[playedIndex].cleanup();
|
|
1164
|
+
storeKeyboardTimeMetadata({
|
|
1165
|
+
event,
|
|
1166
|
+
api,
|
|
1167
|
+
getTimeMetadata: () => {
|
|
1168
|
+
const metadata2 = getMetadata();
|
|
1169
|
+
return metadata2.played[playedIndex] || (metadata2.played[playedIndex] = {});
|
|
1170
|
+
},
|
|
1171
|
+
getShouldStore: () => downCombos.length && keyStates[playedIndex].getDownCombos()[0] === downCombos[0],
|
|
1172
|
+
setRequest: (newRequest) => request = newRequest
|
|
1173
|
+
});
|
|
1174
|
+
onDown?.(toHookApi(api));
|
|
1175
|
+
};
|
|
1176
|
+
const keyup = (event, api) => {
|
|
1177
|
+
const {
|
|
1178
|
+
getStatus,
|
|
1179
|
+
getMetadata,
|
|
1180
|
+
denied
|
|
1181
|
+
} = api, metadata = getMetadata(), key = fromEventToKeyStatusKey(event);
|
|
1182
|
+
if (["denied", "recognized"].includes(localStatuses[playedIndex])) {
|
|
1183
|
+
if (localStatuses[playedIndex] === "denied")
|
|
1184
|
+
denied();
|
|
1185
|
+
for (const { statuses } of keyStates) {
|
|
1186
|
+
if (includes(event.key)(unsupportedKeys))
|
|
1187
|
+
statuses.clear();
|
|
1188
|
+
else
|
|
1189
|
+
statuses.delete(key);
|
|
1190
|
+
}
|
|
1191
|
+
if (!predicateSomeKeyDown(keyStates[playedIndex].statuses)) {
|
|
1192
|
+
if (localStatuses[playedIndex] === "denied" || playedIndex === narrowedKeychord.length - 1 && localStatuses[playedIndex] === "recognized") {
|
|
1193
|
+
playedIndex = 0;
|
|
1194
|
+
for (let i = 0; i < localStatuses.length; i++)
|
|
1195
|
+
localStatuses[i] = "recognizing";
|
|
1196
|
+
for (const { statuses } of keyStates)
|
|
1197
|
+
statuses.clear();
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
onUp?.(toHookApi(api));
|
|
1201
|
+
return;
|
|
1202
|
+
}
|
|
1203
|
+
const downCombos = keyStates[playedIndex].getDownCombos(), matches = keyStates[playedIndex].matchPredicatesByKeycombo[downCombos[0]]?.(keyStates[playedIndex].statuses);
|
|
1204
|
+
keyStates[playedIndex].statuses.delete(key);
|
|
1205
|
+
if (!downCombos.length || !matches) {
|
|
1206
|
+
onUp?.(toHookApi(api));
|
|
1207
|
+
return;
|
|
1208
|
+
}
|
|
1209
|
+
recognize(event, api);
|
|
1210
|
+
const status = getStatus();
|
|
1211
|
+
if (status === "recognizing" && localStatuses[playedIndex] === "recognized" || status === "recognized") {
|
|
1212
|
+
metadata.played[playedIndex] = {
|
|
1213
|
+
...metadata.played[playedIndex],
|
|
1214
|
+
released: downCombos[0]
|
|
1215
|
+
};
|
|
1216
|
+
}
|
|
1217
|
+
if (preventsDefaultUnlessDenied)
|
|
1218
|
+
event.preventDefault();
|
|
1219
|
+
if (playedIndex === narrowedKeychord.length - 1 && !predicateSomeKeyDown(keyStates[playedIndex].statuses)) {
|
|
1220
|
+
playedIndex = 0;
|
|
1221
|
+
for (let i = 0; i < localStatuses.length; i++)
|
|
1222
|
+
localStatuses[i] = "recognizing";
|
|
1223
|
+
for (const { statuses } of keyStates)
|
|
1224
|
+
statuses.clear();
|
|
1225
|
+
}
|
|
1226
|
+
onUp?.(toHookApi(api));
|
|
1227
|
+
};
|
|
1228
|
+
const recognize = (event, api) => {
|
|
1229
|
+
const { getMetadata, recognized, denied } = api, metadata = getMetadata();
|
|
1230
|
+
if (metadata.played[playedIndex].duration < minDuration) {
|
|
1231
|
+
denied();
|
|
1232
|
+
return;
|
|
1233
|
+
}
|
|
1234
|
+
if (playedIndex === narrowedKeychord.length - 1) {
|
|
1235
|
+
recognized();
|
|
1236
|
+
localStatuses[playedIndex] = "recognized";
|
|
1237
|
+
return;
|
|
1238
|
+
}
|
|
1239
|
+
localStatuses[playedIndex] = "recognized";
|
|
1240
|
+
};
|
|
1241
|
+
const visibilitychange = (event, api) => {
|
|
1242
|
+
if (document.visibilityState === "hidden") {
|
|
1243
|
+
for (const { statuses } of keyStates)
|
|
1244
|
+
statuses.clear();
|
|
1245
|
+
localStatuses[playedIndex] = "recognizing";
|
|
1246
|
+
keyStates[playedIndex].cleanup();
|
|
1247
|
+
playedIndex = 0;
|
|
1248
|
+
}
|
|
1249
|
+
onVisibilitychange?.(toHookApi(api));
|
|
1250
|
+
};
|
|
1251
|
+
return {
|
|
1252
|
+
keydown,
|
|
1253
|
+
keyup,
|
|
1254
|
+
visibilitychange
|
|
1255
|
+
};
|
|
1256
|
+
}
|
|
1257
|
+
const unsupportedAliases = ["meta", "command", "cmd"];
|
|
1258
|
+
const unsupportedKeys = ["Meta"];
|
|
1259
|
+
|
|
1260
|
+
function createKonami(options = {}) {
|
|
1261
|
+
return createKeychord("up up down down left right left right b a enter", options);
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
const defaultOptions$f = {
|
|
1265
|
+
minDuration: 0,
|
|
1266
|
+
minDistance: 0,
|
|
1267
|
+
getMousemoveTarget: (event) => event.target
|
|
1268
|
+
};
|
|
1269
|
+
function createMousepress(options = {}) {
|
|
1270
|
+
const {
|
|
1271
|
+
minDuration,
|
|
1272
|
+
minDistance,
|
|
1273
|
+
getMousemoveTarget,
|
|
1274
|
+
onDown,
|
|
1275
|
+
onLeave,
|
|
1276
|
+
onMove,
|
|
1277
|
+
onUp
|
|
1278
|
+
} = { ...defaultOptions$f, ...options }, cleanup = (event) => {
|
|
1279
|
+
window.cancelAnimationFrame(request);
|
|
1280
|
+
getMousemoveTarget(event).removeEventListener("mousemove", mousemoveEffect);
|
|
1281
|
+
};
|
|
1282
|
+
let request;
|
|
1283
|
+
let mousemoveEffect;
|
|
1284
|
+
let mouseStatus;
|
|
1285
|
+
const mousedown = (event, api) => {
|
|
1286
|
+
mouseStatus = "down";
|
|
1287
|
+
mousemoveEffect = (event2) => mousemove(event2, api);
|
|
1288
|
+
storePointerStartMetadata(event, api);
|
|
1289
|
+
storePointerMoveMetadata(event, api);
|
|
1290
|
+
storePointerTimeMetadata(
|
|
1291
|
+
event,
|
|
1292
|
+
api,
|
|
1293
|
+
() => mouseStatus === "down",
|
|
1294
|
+
(newRequest) => request = newRequest,
|
|
1295
|
+
recognize
|
|
1296
|
+
);
|
|
1297
|
+
getMousemoveTarget(event).addEventListener("mousemove", mousemoveEffect);
|
|
1298
|
+
onDown?.(toHookApi(api));
|
|
1299
|
+
};
|
|
1300
|
+
const mousemove = (event, api) => {
|
|
1301
|
+
storePointerMoveMetadata(event, api);
|
|
1302
|
+
recognize(event, api);
|
|
1303
|
+
onMove?.(toHookApi(api));
|
|
1304
|
+
};
|
|
1305
|
+
const recognize = (event, api) => {
|
|
1306
|
+
const { getMetadata, recognized } = api, metadata = getMetadata();
|
|
1307
|
+
if (metadata.duration >= minDuration && metadata.distance.straight.fromStart >= minDistance) {
|
|
1308
|
+
recognized();
|
|
1309
|
+
}
|
|
1310
|
+
};
|
|
1311
|
+
const mouseleave = (event, api) => {
|
|
1312
|
+
const { denied } = api;
|
|
1313
|
+
if (mouseStatus === "down") {
|
|
1314
|
+
denied();
|
|
1315
|
+
cleanup(event);
|
|
1316
|
+
mouseStatus = "leave";
|
|
1317
|
+
}
|
|
1318
|
+
onLeave?.(toHookApi(api));
|
|
1319
|
+
};
|
|
1320
|
+
const mouseup = (event, api) => {
|
|
1321
|
+
const { denied } = api;
|
|
1322
|
+
if (mouseStatus !== "down")
|
|
1323
|
+
return;
|
|
1324
|
+
denied();
|
|
1325
|
+
cleanup(event);
|
|
1326
|
+
mouseStatus = "up";
|
|
1327
|
+
onUp?.(toHookApi(api));
|
|
1328
|
+
};
|
|
1329
|
+
return {
|
|
1330
|
+
mousedown,
|
|
1331
|
+
mouseleave,
|
|
1332
|
+
mouseup
|
|
1333
|
+
};
|
|
1334
|
+
}
|
|
1335
|
+
|
|
1336
|
+
const defaultOptions$e = {
|
|
1337
|
+
minDuration: 0,
|
|
1338
|
+
minDistance: 0,
|
|
1339
|
+
minVelocity: 0,
|
|
1340
|
+
getMousemoveTarget: (event) => event.target
|
|
1341
|
+
};
|
|
1342
|
+
function createMouserelease(options = {}) {
|
|
1343
|
+
const {
|
|
1344
|
+
minDuration,
|
|
1345
|
+
minDistance,
|
|
1346
|
+
minVelocity,
|
|
1347
|
+
getMousemoveTarget,
|
|
1348
|
+
onDown,
|
|
1349
|
+
onLeave,
|
|
1350
|
+
onMove,
|
|
1351
|
+
onUp
|
|
1352
|
+
} = { ...defaultOptions$e, ...options }, cleanup = (event) => {
|
|
1353
|
+
window.cancelAnimationFrame(request);
|
|
1354
|
+
getMousemoveTarget(event).removeEventListener("mousemove", mousemoveEffect);
|
|
1355
|
+
};
|
|
1356
|
+
let request;
|
|
1357
|
+
let mousemoveEffect;
|
|
1358
|
+
let mouseStatus;
|
|
1359
|
+
const mousedown = (event, api) => {
|
|
1360
|
+
mouseStatus = "down";
|
|
1361
|
+
mousemoveEffect = (event2) => mousemove(event2, api);
|
|
1362
|
+
storePointerStartMetadata(event, api);
|
|
1363
|
+
storePointerMoveMetadata(event, api);
|
|
1364
|
+
storePointerTimeMetadata(
|
|
1365
|
+
event,
|
|
1366
|
+
api,
|
|
1367
|
+
() => mouseStatus === "down",
|
|
1368
|
+
(newRequest) => request = newRequest
|
|
1369
|
+
);
|
|
1370
|
+
getMousemoveTarget(event).addEventListener("mousemove", mousemoveEffect);
|
|
1371
|
+
onDown?.(toHookApi(api));
|
|
1372
|
+
};
|
|
1373
|
+
const mousemove = (event, api) => {
|
|
1374
|
+
storePointerMoveMetadata(event, api);
|
|
1375
|
+
onMove?.(toHookApi(api));
|
|
1376
|
+
};
|
|
1377
|
+
const mouseleave = (event, api) => {
|
|
1378
|
+
const { denied } = api;
|
|
1379
|
+
if (mouseStatus === "down") {
|
|
1380
|
+
denied();
|
|
1381
|
+
cleanup(event);
|
|
1382
|
+
mouseStatus = "leave";
|
|
1383
|
+
}
|
|
1384
|
+
onLeave?.(toHookApi(api));
|
|
1385
|
+
};
|
|
1386
|
+
const mouseup = (event, api) => {
|
|
1387
|
+
if (mouseStatus !== "down")
|
|
1388
|
+
return;
|
|
1389
|
+
storePointerMoveMetadata(event, api);
|
|
1390
|
+
cleanup(event);
|
|
1391
|
+
mouseStatus = "up";
|
|
1392
|
+
recognize(event, api);
|
|
1393
|
+
onUp?.(toHookApi(api));
|
|
1394
|
+
};
|
|
1395
|
+
const recognize = (event, api) => {
|
|
1396
|
+
const { getMetadata, recognized, denied } = api, metadata = getMetadata();
|
|
1397
|
+
if (metadata.duration >= minDuration && metadata.distance.straight.fromStart >= minDistance && metadata.velocity >= minVelocity) {
|
|
1398
|
+
recognized();
|
|
1399
|
+
} else {
|
|
1400
|
+
denied();
|
|
1401
|
+
}
|
|
1402
|
+
};
|
|
1403
|
+
return {
|
|
1404
|
+
mousedown,
|
|
1405
|
+
mouseleave,
|
|
1406
|
+
mouseup
|
|
1407
|
+
};
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
const defaultOptions$d = {
|
|
1411
|
+
minDuration: 0,
|
|
1412
|
+
minDistance: 0
|
|
1413
|
+
};
|
|
1414
|
+
function createTouchpress(options = {}) {
|
|
1415
|
+
const {
|
|
1416
|
+
minDuration,
|
|
1417
|
+
minDistance,
|
|
1418
|
+
onStart,
|
|
1419
|
+
onCancel,
|
|
1420
|
+
onMove,
|
|
1421
|
+
onEnd
|
|
1422
|
+
} = { ...defaultOptions$d, ...options }, cleanup = () => {
|
|
1423
|
+
window.cancelAnimationFrame(request);
|
|
1424
|
+
};
|
|
1425
|
+
let request;
|
|
1426
|
+
let totalTouches = 0;
|
|
1427
|
+
const touchstart = (event, api) => {
|
|
1428
|
+
const { denied } = api;
|
|
1429
|
+
totalTouches++;
|
|
1430
|
+
if (totalTouches > 1) {
|
|
1431
|
+
cleanup();
|
|
1432
|
+
denied();
|
|
1433
|
+
onStart?.(toHookApi(api));
|
|
1434
|
+
return;
|
|
1435
|
+
}
|
|
1436
|
+
storePointerStartMetadata(event, api);
|
|
1437
|
+
storePointerMoveMetadata(event, api);
|
|
1438
|
+
storePointerTimeMetadata(
|
|
1439
|
+
event,
|
|
1440
|
+
api,
|
|
1441
|
+
() => totalTouches === 1,
|
|
1442
|
+
(newRequest) => request = newRequest,
|
|
1443
|
+
recognize
|
|
1444
|
+
);
|
|
1445
|
+
onStart?.(toHookApi(api));
|
|
1446
|
+
};
|
|
1447
|
+
const touchmove = (event, api) => {
|
|
1448
|
+
const { getStatus } = api;
|
|
1449
|
+
if (getStatus() !== "denied") {
|
|
1450
|
+
storePointerMoveMetadata(event, api);
|
|
1451
|
+
recognize(event, api);
|
|
1452
|
+
}
|
|
1453
|
+
onMove?.(toHookApi(api));
|
|
1454
|
+
};
|
|
1455
|
+
const recognize = (event, api) => {
|
|
1456
|
+
const { getMetadata, recognized } = api, metadata = getMetadata();
|
|
1457
|
+
if (metadata.duration >= minDuration && metadata.distance.straight.fromStart >= minDistance) {
|
|
1458
|
+
recognized();
|
|
1459
|
+
}
|
|
1460
|
+
};
|
|
1461
|
+
const touchcancel = (event, api) => {
|
|
1462
|
+
const { denied } = api;
|
|
1463
|
+
cleanup();
|
|
1464
|
+
denied();
|
|
1465
|
+
totalTouches--;
|
|
1466
|
+
onCancel?.(toHookApi(api));
|
|
1467
|
+
};
|
|
1468
|
+
const touchend = (event, api) => {
|
|
1469
|
+
const { denied } = api;
|
|
1470
|
+
cleanup();
|
|
1471
|
+
denied();
|
|
1472
|
+
totalTouches--;
|
|
1473
|
+
onEnd?.(toHookApi(api));
|
|
1474
|
+
};
|
|
1475
|
+
return {
|
|
1476
|
+
touchstart,
|
|
1477
|
+
touchmove,
|
|
1478
|
+
touchcancel,
|
|
1479
|
+
touchend
|
|
1480
|
+
};
|
|
1481
|
+
}
|
|
1482
|
+
|
|
1483
|
+
const defaultOptions$c = {
|
|
1484
|
+
minDuration: 0,
|
|
1485
|
+
minDistance: 0,
|
|
1486
|
+
minVelocity: 0
|
|
1487
|
+
};
|
|
1488
|
+
function createTouchrelease(options = {}) {
|
|
1489
|
+
const {
|
|
1490
|
+
minDuration,
|
|
1491
|
+
minDistance,
|
|
1492
|
+
minVelocity,
|
|
1493
|
+
onStart,
|
|
1494
|
+
onCancel,
|
|
1495
|
+
onMove,
|
|
1496
|
+
onEnd
|
|
1497
|
+
} = { ...defaultOptions$c, ...options }, cleanup = () => {
|
|
1498
|
+
window.cancelAnimationFrame(request);
|
|
1499
|
+
};
|
|
1500
|
+
let request;
|
|
1501
|
+
let totalTouches = 0;
|
|
1502
|
+
const touchstart = (event, api) => {
|
|
1503
|
+
const { denied } = api;
|
|
1504
|
+
totalTouches++;
|
|
1505
|
+
if (totalTouches > 1) {
|
|
1506
|
+
cleanup();
|
|
1507
|
+
denied();
|
|
1508
|
+
onStart?.(toHookApi(api));
|
|
1509
|
+
return;
|
|
1510
|
+
}
|
|
1511
|
+
storePointerStartMetadata(event, api);
|
|
1512
|
+
storePointerMoveMetadata(event, api);
|
|
1513
|
+
storePointerTimeMetadata(
|
|
1514
|
+
event,
|
|
1515
|
+
api,
|
|
1516
|
+
() => totalTouches === 1,
|
|
1517
|
+
(newRequest) => request = newRequest
|
|
1518
|
+
);
|
|
1519
|
+
onStart?.(toHookApi(api));
|
|
1520
|
+
};
|
|
1521
|
+
const touchmove = (event, api) => {
|
|
1522
|
+
const { getStatus } = api;
|
|
1523
|
+
if (getStatus() !== "denied")
|
|
1524
|
+
storePointerMoveMetadata(event, api);
|
|
1525
|
+
onMove?.(toHookApi(api));
|
|
1526
|
+
};
|
|
1527
|
+
const touchcancel = (event, api) => {
|
|
1528
|
+
const { denied } = api;
|
|
1529
|
+
cleanup();
|
|
1530
|
+
denied();
|
|
1531
|
+
totalTouches--;
|
|
1532
|
+
onCancel?.(toHookApi(api));
|
|
1533
|
+
};
|
|
1534
|
+
const touchend = (event, api) => {
|
|
1535
|
+
const { denied } = api;
|
|
1536
|
+
if (totalTouches !== 1) {
|
|
1537
|
+
cleanup();
|
|
1538
|
+
denied();
|
|
1539
|
+
onEnd?.(toHookApi(api));
|
|
1540
|
+
return;
|
|
1541
|
+
}
|
|
1542
|
+
storePointerMoveMetadata(event, api);
|
|
1543
|
+
cleanup();
|
|
1544
|
+
totalTouches--;
|
|
1545
|
+
recognize(event, api);
|
|
1546
|
+
onEnd?.(toHookApi(api));
|
|
1547
|
+
};
|
|
1548
|
+
const recognize = (event, api) => {
|
|
1549
|
+
const { getMetadata, recognized, denied } = api, metadata = getMetadata();
|
|
1550
|
+
if (metadata.duration >= minDuration && metadata.distance.straight.fromStart >= minDistance && metadata.velocity >= minVelocity) {
|
|
1551
|
+
recognized();
|
|
1552
|
+
} else {
|
|
1553
|
+
denied();
|
|
1554
|
+
}
|
|
1555
|
+
};
|
|
1556
|
+
return {
|
|
1557
|
+
touchstart,
|
|
1558
|
+
touchmove,
|
|
1559
|
+
touchcancel,
|
|
1560
|
+
touchend
|
|
1561
|
+
};
|
|
1562
|
+
}
|
|
1563
|
+
|
|
1564
|
+
const defaultOptions$b = {
|
|
1565
|
+
initial: []
|
|
1566
|
+
};
|
|
1567
|
+
function createKeyStatuses(options = {}) {
|
|
1568
|
+
return createAssociativeArray({
|
|
1569
|
+
...defaultOptions$b,
|
|
1570
|
+
...options,
|
|
1571
|
+
createPredicateKey: (query) => (key) => {
|
|
1572
|
+
for (const prop in query) {
|
|
1573
|
+
if (query[prop] !== key[prop]) {
|
|
1574
|
+
return false;
|
|
1575
|
+
}
|
|
1576
|
+
}
|
|
1577
|
+
return true;
|
|
1578
|
+
}
|
|
1579
|
+
});
|
|
1580
|
+
}
|
|
1581
|
+
function predicateDown(status) {
|
|
1582
|
+
return status === "down";
|
|
1583
|
+
}
|
|
1584
|
+
function predicateSomeKeyDown(statuses) {
|
|
1585
|
+
return includes("down")(statuses.toValues());
|
|
1586
|
+
}
|
|
1587
|
+
|
|
1588
|
+
function fromComboToAliases(combo) {
|
|
1589
|
+
const delimiter = "+";
|
|
1590
|
+
return pipe(
|
|
1591
|
+
unique(),
|
|
1592
|
+
map((name) => name === "" ? delimiter : name.toLowerCase()),
|
|
1593
|
+
toArray()
|
|
1594
|
+
)(combo.split(delimiter));
|
|
1595
|
+
}
|
|
1596
|
+
|
|
1597
|
+
function fromAliasToKeyStatusKey(alias) {
|
|
1598
|
+
if (alias in keysByAlias) {
|
|
1599
|
+
return { key: keysByAlias[alias] };
|
|
1600
|
+
}
|
|
1601
|
+
return {
|
|
1602
|
+
code: (() => {
|
|
1603
|
+
if (alias in codesByAlias)
|
|
1604
|
+
return codesByAlias[alias];
|
|
1605
|
+
if (letterRE.test(alias))
|
|
1606
|
+
return `Key${alias.toUpperCase()}`;
|
|
1607
|
+
if (digitRE.test(alias))
|
|
1608
|
+
return `Digit${alias}`;
|
|
1609
|
+
if (functionRE.test(alias))
|
|
1610
|
+
return alias.toUpperCase();
|
|
1611
|
+
return "unsupported";
|
|
1612
|
+
})()
|
|
1613
|
+
};
|
|
1614
|
+
}
|
|
1615
|
+
const digitRE = /^[0-9]$/;
|
|
1616
|
+
const letterRE = /^[a-zA-Z]$/;
|
|
1617
|
+
const functionRE = /^[fF][0-9]{1,2}$/;
|
|
1618
|
+
const codesByAlias = {
|
|
1619
|
+
"`": "Backquote",
|
|
1620
|
+
"~": "Backquote",
|
|
1621
|
+
"-": "Minus",
|
|
1622
|
+
_: "Minus",
|
|
1623
|
+
"=": "Equal",
|
|
1624
|
+
"+": "Equal",
|
|
1625
|
+
"[": "BracketLeft",
|
|
1626
|
+
"{": "BracketLeft",
|
|
1627
|
+
"]": "BracketRight",
|
|
1628
|
+
"}": "BracketRight",
|
|
1629
|
+
"\\": "Backslash",
|
|
1630
|
+
"|": "Backslash",
|
|
1631
|
+
";": "Semicolon",
|
|
1632
|
+
":": "Semicolon",
|
|
1633
|
+
"'": "Quote",
|
|
1634
|
+
'"': "Quote",
|
|
1635
|
+
",": "Comma",
|
|
1636
|
+
"<": "Comma",
|
|
1637
|
+
".": "Period",
|
|
1638
|
+
">": "Period",
|
|
1639
|
+
"/": "Slash",
|
|
1640
|
+
"?": "Slash",
|
|
1641
|
+
"!": "Digit1",
|
|
1642
|
+
"@": "Digit2",
|
|
1643
|
+
"#": "Digit3",
|
|
1644
|
+
$: "Digit4",
|
|
1645
|
+
"%": "Digit5",
|
|
1646
|
+
"^": "Digit6",
|
|
1647
|
+
"&": "Digit7",
|
|
1648
|
+
"*": "Digit8",
|
|
1649
|
+
"(": "Digit9",
|
|
1650
|
+
")": "Digit0",
|
|
1651
|
+
up: "ArrowUp",
|
|
1652
|
+
down: "ArrowDown",
|
|
1653
|
+
left: "ArrowLeft",
|
|
1654
|
+
right: "ArrowRight",
|
|
1655
|
+
enter: "Enter",
|
|
1656
|
+
space: "Space",
|
|
1657
|
+
tab: "Tab",
|
|
1658
|
+
esc: "Escape",
|
|
1659
|
+
backspace: "Backspace",
|
|
1660
|
+
delete: "Delete",
|
|
1661
|
+
home: "Home",
|
|
1662
|
+
end: "End",
|
|
1663
|
+
pagedown: "PageDown",
|
|
1664
|
+
pageup: "PageUp",
|
|
1665
|
+
capslock: "CapsLock",
|
|
1666
|
+
camera: "Camera"
|
|
1667
|
+
};
|
|
1668
|
+
const keysByAlias = {
|
|
1669
|
+
alt: "Alt",
|
|
1670
|
+
opt: "Alt",
|
|
1671
|
+
option: "Alt",
|
|
1672
|
+
ctrl: "Control",
|
|
1673
|
+
control: "Control",
|
|
1674
|
+
meta: "Meta",
|
|
1675
|
+
cmd: "Meta",
|
|
1676
|
+
command: "Meta",
|
|
1677
|
+
shift: "Shift"
|
|
1678
|
+
};
|
|
1679
|
+
|
|
1680
|
+
const defaultOptions$a = {
|
|
1681
|
+
toKey: (alias) => fromAliasToKeyStatusKey(alias)
|
|
1682
|
+
};
|
|
1683
|
+
const createPredicateKeycomboDown = (keycombo, options = {}) => {
|
|
1684
|
+
const { toKey } = { ...defaultOptions$a, ...options }, keys = pipe(
|
|
1685
|
+
fromComboToAliases,
|
|
1686
|
+
map(toKey)
|
|
1687
|
+
)(keycombo);
|
|
1688
|
+
return (statuses) => {
|
|
1689
|
+
const { toValue } = statuses;
|
|
1690
|
+
return every(pipe(
|
|
1691
|
+
toValue,
|
|
1692
|
+
predicateDown
|
|
1693
|
+
))(keys);
|
|
1694
|
+
};
|
|
1695
|
+
};
|
|
1696
|
+
|
|
1697
|
+
function fromEventToAliases(event) {
|
|
1698
|
+
if (event.shiftKey && event.code in aliasesByShiftCode) {
|
|
1699
|
+
return [aliasesByShiftCode[event.code]];
|
|
1700
|
+
}
|
|
1701
|
+
if (event.key in aliasListsByModifier) {
|
|
1702
|
+
return aliasListsByModifier[event.key];
|
|
1703
|
+
}
|
|
1704
|
+
return event.code in aliasesByCode ? [aliasesByCode[event.code]] : [event.code.match(aliasCaptureRE)?.[1].toLowerCase() || "unsupported"];
|
|
1705
|
+
}
|
|
1706
|
+
const aliasCaptureRE = /^(?:Digit|Key)?(F[0-9]{1,2}|[0-9]|[A-Z])$/;
|
|
1707
|
+
const aliasesByCode = {
|
|
1708
|
+
Backquote: "`",
|
|
1709
|
+
Minus: "-",
|
|
1710
|
+
Equal: "=",
|
|
1711
|
+
BracketLeft: "[",
|
|
1712
|
+
BracketRight: "]",
|
|
1713
|
+
Backslash: "\\",
|
|
1714
|
+
Semicolon: ";",
|
|
1715
|
+
Quote: "'",
|
|
1716
|
+
Comma: ",",
|
|
1717
|
+
Period: ".",
|
|
1718
|
+
Slash: "/",
|
|
1719
|
+
ArrowUp: "up",
|
|
1720
|
+
ArrowDown: "down",
|
|
1721
|
+
ArrowLeft: "left",
|
|
1722
|
+
ArrowRight: "right",
|
|
1723
|
+
Enter: "enter",
|
|
1724
|
+
Space: "space",
|
|
1725
|
+
Tab: "tab",
|
|
1726
|
+
Escape: "esc",
|
|
1727
|
+
Backspace: "backspace",
|
|
1728
|
+
Delete: "delete",
|
|
1729
|
+
Home: "home",
|
|
1730
|
+
End: "end",
|
|
1731
|
+
PageDown: "pagedown",
|
|
1732
|
+
PageUp: "pageup",
|
|
1733
|
+
CapsLock: "capslock",
|
|
1734
|
+
Camera: "camera"
|
|
1735
|
+
};
|
|
1736
|
+
const aliasesByShiftCode = {
|
|
1737
|
+
Backquote: "~",
|
|
1738
|
+
Minus: "_",
|
|
1739
|
+
Equal: "+",
|
|
1740
|
+
BracketLeft: "{",
|
|
1741
|
+
BracketRight: "}",
|
|
1742
|
+
Backslash: "|",
|
|
1743
|
+
Semicolon: ":",
|
|
1744
|
+
Quote: '"',
|
|
1745
|
+
Comma: "<",
|
|
1746
|
+
Period: ">",
|
|
1747
|
+
Slash: "?",
|
|
1748
|
+
Digit1: "!",
|
|
1749
|
+
Digit2: "@",
|
|
1750
|
+
Digit3: "#",
|
|
1751
|
+
Digit4: "$",
|
|
1752
|
+
Digit5: "%",
|
|
1753
|
+
Digit6: "^",
|
|
1754
|
+
Digit7: "&",
|
|
1755
|
+
Digit8: "*",
|
|
1756
|
+
Digit9: "(",
|
|
1757
|
+
Digit0: ")"
|
|
1758
|
+
};
|
|
1759
|
+
const aliasListsByModifier = {
|
|
1760
|
+
Alt: ["alt", "option", "opt"],
|
|
1761
|
+
Control: ["control", "ctrl"],
|
|
1762
|
+
Meta: ["meta", "command", "cmd"],
|
|
1763
|
+
Shift: ["shift"]
|
|
1764
|
+
};
|
|
1765
|
+
|
|
1766
|
+
const defaultOptions$9 = {
|
|
1767
|
+
toKey: (alias) => fromAliasToKeyStatusKey(alias),
|
|
1768
|
+
toAliases: (event) => fromEventToAliases(event)
|
|
1769
|
+
};
|
|
1770
|
+
const createPredicateKeycomboMatch = (keycombo, options = {}) => {
|
|
1771
|
+
const { toKey, toAliases } = { ...defaultOptions$9, ...options }, aliases = fromComboToAliases(keycombo), keys = map(toKey)(aliases);
|
|
1772
|
+
return (statuses) => {
|
|
1773
|
+
const { toValue } = statuses;
|
|
1774
|
+
return every(pipe(
|
|
1775
|
+
toValue,
|
|
1776
|
+
predicateDown
|
|
1777
|
+
))(keys) && every(
|
|
1778
|
+
([key, value]) => value === "up" || some(
|
|
1779
|
+
(alias) => includes(alias)(aliases)
|
|
1780
|
+
)(toAliases(key))
|
|
1781
|
+
)(statuses.toEntries());
|
|
1782
|
+
};
|
|
1783
|
+
};
|
|
1784
|
+
|
|
1785
|
+
function createKeyState({
|
|
1786
|
+
keycomboOrKeycombos,
|
|
1787
|
+
unsupportedAliases,
|
|
1788
|
+
toKey,
|
|
1789
|
+
toAliases,
|
|
1790
|
+
getRequest
|
|
1791
|
+
}) {
|
|
1792
|
+
const narrowedKeycombos = createFilter(
|
|
1793
|
+
(keycombo) => !some(
|
|
1794
|
+
(alias) => includes(alias)(unsupportedAliases)
|
|
1795
|
+
)(fromComboToAliases(keycombo))
|
|
1796
|
+
)(Array.isArray(keycomboOrKeycombos) ? keycomboOrKeycombos : [keycomboOrKeycombos]), createPredicateKeycomboDownOptions = { toKey }, downPredicatesByKeycombo = (() => {
|
|
1797
|
+
const predicates = [];
|
|
1798
|
+
for (const keycombo of narrowedKeycombos) {
|
|
1799
|
+
predicates.push([
|
|
1800
|
+
keycombo,
|
|
1801
|
+
createPredicateKeycomboDown(
|
|
1802
|
+
keycombo,
|
|
1803
|
+
createPredicateKeycomboDownOptions
|
|
1804
|
+
)
|
|
1805
|
+
]);
|
|
165
1806
|
}
|
|
166
|
-
return
|
|
1807
|
+
return predicates;
|
|
1808
|
+
})(), createPredicateKeycomboMatchOptions = { ...createPredicateKeycomboDownOptions, toAliases }, matchPredicatesByKeycombo = (() => {
|
|
1809
|
+
const predicates = {};
|
|
1810
|
+
for (const keycombo of narrowedKeycombos) {
|
|
1811
|
+
predicates[keycombo] = createPredicateKeycomboMatch(
|
|
1812
|
+
keycombo,
|
|
1813
|
+
createPredicateKeycomboMatchOptions
|
|
1814
|
+
);
|
|
1815
|
+
}
|
|
1816
|
+
return predicates;
|
|
1817
|
+
})(), validAliases = pipe(
|
|
1818
|
+
flatMap(fromComboToAliases),
|
|
1819
|
+
unique(),
|
|
1820
|
+
toArray()
|
|
1821
|
+
)(narrowedKeycombos), getDownCombos = () => pipe(
|
|
1822
|
+
filter(([, predicate]) => predicate(statuses)),
|
|
1823
|
+
map(([keycombo]) => [keycombo, fromComboToAliases(keycombo)]),
|
|
1824
|
+
sort(([, aliasesA], [, aliasesB]) => aliasesB.length - aliasesA.length),
|
|
1825
|
+
map(([keycombo]) => keycombo),
|
|
1826
|
+
toArray()
|
|
1827
|
+
)(downPredicatesByKeycombo), predicateValid = (event) => {
|
|
1828
|
+
const aliases = toAliases(event);
|
|
1829
|
+
return some(
|
|
1830
|
+
(validAlias) => includes(validAlias)(aliases)
|
|
1831
|
+
)(validAliases);
|
|
1832
|
+
}, cleanup = () => {
|
|
1833
|
+
window.cancelAnimationFrame(getRequest());
|
|
1834
|
+
}, statuses = createKeyStatuses();
|
|
1835
|
+
return {
|
|
1836
|
+
narrowedKeycombos,
|
|
1837
|
+
createPredicateKeycomboDownOptions,
|
|
1838
|
+
downPredicatesByKeycombo,
|
|
1839
|
+
createPredicateKeycomboMatchOptions,
|
|
1840
|
+
matchPredicatesByKeycombo,
|
|
1841
|
+
validAliases,
|
|
1842
|
+
getDownCombos,
|
|
1843
|
+
predicateValid,
|
|
1844
|
+
cleanup,
|
|
1845
|
+
statuses
|
|
167
1846
|
};
|
|
168
1847
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
(sliced) => compare ? sliced.sort(compare) : sliced.sort()
|
|
174
|
-
);
|
|
1848
|
+
|
|
1849
|
+
function toLength() {
|
|
1850
|
+
return function toLengthFn(data) {
|
|
1851
|
+
return [...data].length;
|
|
175
1852
|
};
|
|
176
1853
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
1854
|
+
|
|
1855
|
+
const fromComboToAliasesLength = pipe(
|
|
1856
|
+
fromComboToAliases,
|
|
1857
|
+
toLength()
|
|
1858
|
+
);
|
|
1859
|
+
|
|
1860
|
+
function fromEventToKeyStatusKey({ key, code }) {
|
|
1861
|
+
return includes(key)(modifiers) ? { key } : { code };
|
|
181
1862
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
1863
|
+
const modifiers = ["Alt", "Control", "Meta", "Shift"];
|
|
1864
|
+
|
|
1865
|
+
function toDirection(angle, unit = "degrees") {
|
|
1866
|
+
return Object.keys(directions).find((direction) => directions[direction][unit](angle));
|
|
186
1867
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
1868
|
+
const directions = {
|
|
1869
|
+
up: {
|
|
1870
|
+
degrees: (degrees) => degrees >= 67.5 && degrees <= 112.5,
|
|
1871
|
+
radians: (radians) => radians >= 0.375 * Math.PI && radians <= 0.625 * Math.PI
|
|
1872
|
+
},
|
|
1873
|
+
upRight: {
|
|
1874
|
+
degrees: (degrees) => degrees >= 22.5 && degrees < 67.5,
|
|
1875
|
+
radians: (radians) => radians >= 0.125 * Math.PI && radians < 0.375 * Math.PI
|
|
1876
|
+
},
|
|
1877
|
+
right: {
|
|
1878
|
+
degrees: (degrees) => degrees > 337.5 && degrees <= 360 || degrees < 22.5 && degrees >= 0,
|
|
1879
|
+
radians: (radians) => radians > 1.875 * Math.PI && radians <= 2 * Math.PI || radians < 0.125 * Math.PI && radians >= 0
|
|
1880
|
+
},
|
|
1881
|
+
downRight: {
|
|
1882
|
+
degrees: (degrees) => degrees > 292.5 && degrees <= 337.5,
|
|
1883
|
+
radians: (radians) => radians > 1.625 * Math.PI && radians <= 1.875 * Math.PI
|
|
1884
|
+
},
|
|
1885
|
+
down: {
|
|
1886
|
+
degrees: (degrees) => degrees >= 247.5 && degrees <= 292.5,
|
|
1887
|
+
radians: (radians) => radians >= 1.375 * Math.PI && radians <= 1.625 * Math.PI
|
|
1888
|
+
},
|
|
1889
|
+
downLeft: {
|
|
1890
|
+
degrees: (degrees) => degrees >= 202.5 && degrees < 247.5,
|
|
1891
|
+
radians: (radians) => radians >= 1.125 * Math.PI && radians < 1.375 * Math.PI
|
|
1892
|
+
},
|
|
1893
|
+
left: {
|
|
1894
|
+
degrees: (degrees) => degrees > 157.5 && degrees < 202.5,
|
|
1895
|
+
radians: (radians) => radians > 0.875 * Math.PI && radians < 1.125 * Math.PI
|
|
1896
|
+
},
|
|
1897
|
+
upLeft: {
|
|
1898
|
+
degrees: (degrees) => degrees > 112.5 && degrees <= 157.5,
|
|
1899
|
+
radians: (radians) => radians > 0.625 * Math.PI && radians <= 0.875 * Math.PI
|
|
1900
|
+
}
|
|
1901
|
+
};
|
|
1902
|
+
|
|
1903
|
+
function toHookApi({
|
|
1904
|
+
getSequence,
|
|
1905
|
+
getStatus,
|
|
1906
|
+
getMetadata
|
|
1907
|
+
}) {
|
|
1908
|
+
return {
|
|
1909
|
+
sequence: getSequence(),
|
|
1910
|
+
status: getStatus(),
|
|
1911
|
+
metadata: getMetadata()
|
|
191
1912
|
};
|
|
192
1913
|
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
return {
|
|
200
|
-
outcome,
|
|
201
|
-
predicate: (determinant) => determinant >= lowerBound && determinant < upperBound || determinant < 0 && index === 0 || index === predicates.length - 1
|
|
202
|
-
};
|
|
203
|
-
})(potentialities);
|
|
204
|
-
return (determinant) => find(({ predicate }) => predicate(determinant))(predicates).outcome;
|
|
1914
|
+
|
|
1915
|
+
function toMousePoint(event) {
|
|
1916
|
+
return {
|
|
1917
|
+
x: event.clientX,
|
|
1918
|
+
y: event.clientY
|
|
1919
|
+
};
|
|
205
1920
|
}
|
|
206
|
-
function
|
|
207
|
-
return
|
|
208
|
-
|
|
209
|
-
|
|
1921
|
+
function toTouchMovePoint(event) {
|
|
1922
|
+
return {
|
|
1923
|
+
x: event.touches.item(0).clientX,
|
|
1924
|
+
y: event.touches.item(0).clientY
|
|
210
1925
|
};
|
|
211
1926
|
}
|
|
212
|
-
function
|
|
213
|
-
return
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
entries.push([key, object[key]]);
|
|
217
|
-
}
|
|
218
|
-
return entries;
|
|
1927
|
+
function toTouchEndPoint(event) {
|
|
1928
|
+
return {
|
|
1929
|
+
x: event.changedTouches.item(0).clientX,
|
|
1930
|
+
y: event.changedTouches.item(0).clientY
|
|
219
1931
|
};
|
|
220
1932
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
}
|
|
227
|
-
return keys;
|
|
1933
|
+
|
|
1934
|
+
function toPolarCoordinates({ xA, xB, yA, yB }) {
|
|
1935
|
+
const distance = Math.hypot(xB - xA, yB - yA), angle = Math.atan2(yA - yB, xB - xA), radians = angle >= 0 ? angle : 2 * Math.PI + angle, degrees = radians * 180 / Math.PI;
|
|
1936
|
+
return {
|
|
1937
|
+
distance,
|
|
1938
|
+
angle: { radians, degrees }
|
|
228
1939
|
};
|
|
229
1940
|
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
1941
|
+
|
|
1942
|
+
const initialMetadata$3 = {
|
|
1943
|
+
times: {
|
|
1944
|
+
start: 0,
|
|
1945
|
+
end: 0
|
|
1946
|
+
},
|
|
1947
|
+
duration: 0
|
|
1948
|
+
};
|
|
1949
|
+
function storeKeyboardTimeMetadata({
|
|
1950
|
+
event,
|
|
1951
|
+
api,
|
|
1952
|
+
getTimeMetadata,
|
|
1953
|
+
getShouldStore,
|
|
1954
|
+
setRequest,
|
|
1955
|
+
recognize
|
|
1956
|
+
}) {
|
|
1957
|
+
if (!getShouldStore())
|
|
1958
|
+
return;
|
|
1959
|
+
const { getStatus, onRecognized } = api, timeMetadata = getTimeMetadata();
|
|
1960
|
+
if (!timeMetadata.times)
|
|
1961
|
+
timeMetadata.times = createClone()(initialMetadata$3.times);
|
|
1962
|
+
timeMetadata.times.start = Math.round(event.timeStamp);
|
|
1963
|
+
timeMetadata.times.end = Math.round(event.timeStamp);
|
|
1964
|
+
const storeDuration = () => {
|
|
1965
|
+
const request = requestAnimationFrame((timestamp) => {
|
|
1966
|
+
if (!getShouldStore())
|
|
1967
|
+
return;
|
|
1968
|
+
timeMetadata.times.end = Math.round(timestamp);
|
|
1969
|
+
timeMetadata.duration = Math.max(0, timeMetadata.times.end - timeMetadata.times.start);
|
|
1970
|
+
if (recognize) {
|
|
1971
|
+
recognize(event, api);
|
|
1972
|
+
if (getStatus() === "recognized")
|
|
1973
|
+
onRecognized(event);
|
|
235
1974
|
}
|
|
236
|
-
|
|
237
|
-
|
|
1975
|
+
storeDuration();
|
|
1976
|
+
});
|
|
1977
|
+
setRequest(request);
|
|
238
1978
|
};
|
|
1979
|
+
storeDuration();
|
|
239
1980
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
1981
|
+
|
|
1982
|
+
const initialMetadata$2 = {
|
|
1983
|
+
points: {
|
|
1984
|
+
start: { x: 0, y: 0 },
|
|
1985
|
+
end: { x: 0, y: 0 }
|
|
1986
|
+
}
|
|
1987
|
+
};
|
|
1988
|
+
function storePointerStartMetadata(event, api) {
|
|
1989
|
+
const { getMetadata } = api, metadata = getMetadata();
|
|
1990
|
+
const point = event instanceof MouseEvent ? toMousePoint(event) : toTouchMovePoint(event);
|
|
1991
|
+
if (!metadata.points)
|
|
1992
|
+
metadata.points = createClone()(initialMetadata$2.points);
|
|
1993
|
+
metadata.points.start = point;
|
|
1994
|
+
metadata.points.end = point;
|
|
1995
|
+
}
|
|
1996
|
+
|
|
1997
|
+
const initialMetadata$1 = {
|
|
1998
|
+
distance: {
|
|
1999
|
+
straight: {
|
|
2000
|
+
fromStart: 0,
|
|
2001
|
+
fromPrevious: 0
|
|
2002
|
+
},
|
|
2003
|
+
horizontal: {
|
|
2004
|
+
fromStart: 0,
|
|
2005
|
+
fromPrevious: 0
|
|
2006
|
+
},
|
|
2007
|
+
vertical: {
|
|
2008
|
+
fromStart: 0,
|
|
2009
|
+
fromPrevious: 0
|
|
2010
|
+
}
|
|
2011
|
+
},
|
|
2012
|
+
angle: {
|
|
2013
|
+
fromPrevious: { radians: 0, degrees: 0 },
|
|
2014
|
+
fromStart: { radians: 0, degrees: 0 }
|
|
2015
|
+
},
|
|
2016
|
+
direction: {
|
|
2017
|
+
fromPrevious: "up",
|
|
2018
|
+
fromStart: "up"
|
|
2019
|
+
}
|
|
2020
|
+
};
|
|
2021
|
+
function storePointerMoveMetadata(event, api) {
|
|
2022
|
+
const { getMetadata } = api, metadata = getMetadata();
|
|
2023
|
+
if (!metadata.distance) {
|
|
2024
|
+
metadata.distance = createClone()(initialMetadata$1.distance);
|
|
2025
|
+
metadata.angle = createClone()(initialMetadata$1.angle);
|
|
2026
|
+
metadata.direction = createClone()(initialMetadata$1.direction);
|
|
2027
|
+
}
|
|
2028
|
+
const { x: previousX, y: previousY } = metadata.points.end, { x: startX, y: startY } = metadata.points.start, { x: newX, y: newY } = (() => {
|
|
2029
|
+
if (event instanceof MouseEvent) {
|
|
2030
|
+
return toMousePoint(event);
|
|
2031
|
+
}
|
|
2032
|
+
if (event instanceof TouchEvent) {
|
|
2033
|
+
if (event.type === "touchmove") {
|
|
2034
|
+
return toTouchMovePoint(event);
|
|
245
2035
|
}
|
|
2036
|
+
return toTouchEndPoint(event);
|
|
246
2037
|
}
|
|
247
|
-
|
|
2038
|
+
})(), { distance: distanceFromPrevious, angle: angleFromPrevious } = toPolarCoordinates({
|
|
2039
|
+
xA: previousX,
|
|
2040
|
+
xB: newX,
|
|
2041
|
+
yA: previousY,
|
|
2042
|
+
yB: newY
|
|
2043
|
+
}), { distance: distanceFromStart, angle: angleFromStart } = toPolarCoordinates({
|
|
2044
|
+
xA: startX,
|
|
2045
|
+
xB: newX,
|
|
2046
|
+
yA: startY,
|
|
2047
|
+
yB: newY
|
|
2048
|
+
});
|
|
2049
|
+
metadata.distance.straight.fromPrevious = distanceFromPrevious;
|
|
2050
|
+
metadata.distance.horizontal.fromPrevious = newX - previousX;
|
|
2051
|
+
metadata.distance.vertical.fromPrevious = newY - previousY;
|
|
2052
|
+
metadata.angle.fromPrevious = angleFromPrevious;
|
|
2053
|
+
metadata.direction.fromPrevious = toDirection(angleFromPrevious.degrees);
|
|
2054
|
+
metadata.distance.straight.fromStart = distanceFromStart;
|
|
2055
|
+
metadata.distance.horizontal.fromStart = newX - startX;
|
|
2056
|
+
metadata.distance.vertical.fromStart = newY - startY;
|
|
2057
|
+
metadata.angle.fromStart = angleFromStart;
|
|
2058
|
+
metadata.direction.fromStart = toDirection(angleFromStart.degrees);
|
|
2059
|
+
metadata.points.end = { x: newX, y: newY };
|
|
2060
|
+
}
|
|
2061
|
+
|
|
2062
|
+
const initialMetadata = {
|
|
2063
|
+
times: {
|
|
2064
|
+
start: 0,
|
|
2065
|
+
end: 0
|
|
2066
|
+
},
|
|
2067
|
+
duration: 0,
|
|
2068
|
+
velocity: 0
|
|
2069
|
+
};
|
|
2070
|
+
function storePointerTimeMetadata(event, api, getShouldStore, setRequest, recognize) {
|
|
2071
|
+
const { getMetadata, getStatus, onRecognized } = api, metadata = getMetadata();
|
|
2072
|
+
if (!metadata.times) {
|
|
2073
|
+
metadata.times = createClone()(initialMetadata.times);
|
|
2074
|
+
}
|
|
2075
|
+
metadata.times.start = Math.round(event.timeStamp);
|
|
2076
|
+
metadata.times.end = Math.round(event.timeStamp);
|
|
2077
|
+
let previousTime = metadata.times.start;
|
|
2078
|
+
const storeDuration = () => {
|
|
2079
|
+
const request = requestAnimationFrame((timestamp) => {
|
|
2080
|
+
if (getShouldStore()) {
|
|
2081
|
+
previousTime = metadata.times.end;
|
|
2082
|
+
metadata.times.end = Math.round(timestamp);
|
|
2083
|
+
metadata.duration = Math.max(0, metadata.times.end - metadata.times.start);
|
|
2084
|
+
const durationFromPrevious = Math.max(0, metadata.times.end - previousTime);
|
|
2085
|
+
metadata.velocity = metadata.distance.straight.fromPrevious / durationFromPrevious;
|
|
2086
|
+
recognize?.(event, api);
|
|
2087
|
+
if (getStatus() === "recognized")
|
|
2088
|
+
onRecognized(event);
|
|
2089
|
+
storeDuration();
|
|
2090
|
+
}
|
|
2091
|
+
});
|
|
2092
|
+
setRequest(request);
|
|
248
2093
|
};
|
|
2094
|
+
storeDuration();
|
|
249
2095
|
}
|
|
250
|
-
|
|
251
|
-
|
|
2096
|
+
|
|
2097
|
+
function defineGraph(nodes, edges) {
|
|
2098
|
+
return { nodes, edges };
|
|
252
2099
|
}
|
|
253
|
-
function
|
|
254
|
-
return
|
|
2100
|
+
function defineGraphNodes(nodes) {
|
|
2101
|
+
return nodes;
|
|
255
2102
|
}
|
|
256
|
-
function
|
|
257
|
-
return
|
|
2103
|
+
function defineGraphEdges(edges) {
|
|
2104
|
+
return edges;
|
|
258
2105
|
}
|
|
259
|
-
function
|
|
260
|
-
return
|
|
261
|
-
if (elementIsCandidate && predicateFocusable(element))
|
|
262
|
-
return element;
|
|
263
|
-
switch (order) {
|
|
264
|
-
case "first":
|
|
265
|
-
for (let i = 0; i < element.children.length; i++) {
|
|
266
|
-
const focusable = createToFocusable(order, true)(element.children[i]);
|
|
267
|
-
if (focusable)
|
|
268
|
-
return focusable;
|
|
269
|
-
}
|
|
270
|
-
break;
|
|
271
|
-
case "last":
|
|
272
|
-
for (let i = element.children.length - 1; i > -1; i--) {
|
|
273
|
-
const focusable = createToFocusable(order, true)(element.children[i]);
|
|
274
|
-
if (focusable)
|
|
275
|
-
return focusable;
|
|
276
|
-
}
|
|
277
|
-
break;
|
|
278
|
-
}
|
|
279
|
-
};
|
|
2106
|
+
function defineGraphNode(node) {
|
|
2107
|
+
return node;
|
|
280
2108
|
}
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
this.state = state;
|
|
284
|
-
}
|
|
285
|
-
pipe(...fns) {
|
|
286
|
-
return createReduce((piped, fn, index) => fn(piped, index), this.state)(fns);
|
|
287
|
-
}
|
|
288
|
-
async pipeAsync(...fns) {
|
|
289
|
-
return await createReduceAsync(
|
|
290
|
-
async (piped, fn, index) => await fn(piped, index),
|
|
291
|
-
this.state
|
|
292
|
-
)(fns);
|
|
293
|
-
}
|
|
2109
|
+
function defineGraphEdge(from, to, predicateTraversable) {
|
|
2110
|
+
return { from, to, predicateTraversable };
|
|
294
2111
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
return name in keysByName ? keysByName[name] : name;
|
|
2112
|
+
function defineAsyncGraph(nodes, edges) {
|
|
2113
|
+
return { nodes, edges };
|
|
298
2114
|
}
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
right: "ArrowRight",
|
|
302
|
-
down: "ArrowDown",
|
|
303
|
-
left: "ArrowLeft",
|
|
304
|
-
enter: "Enter",
|
|
305
|
-
backspace: "Backspace",
|
|
306
|
-
tab: "Tab",
|
|
307
|
-
space: " ",
|
|
308
|
-
shift: "Shift",
|
|
309
|
-
meta: "Meta",
|
|
310
|
-
command: "Meta",
|
|
311
|
-
cmd: "Meta",
|
|
312
|
-
control: "Control",
|
|
313
|
-
ctrl: "Control",
|
|
314
|
-
alt: "Alt",
|
|
315
|
-
opt: "Alt",
|
|
316
|
-
option: "Alt",
|
|
317
|
-
fn: "Fn",
|
|
318
|
-
capslock: "CapsLock",
|
|
319
|
-
end: "End",
|
|
320
|
-
home: "Home",
|
|
321
|
-
pagedown: "PageDown",
|
|
322
|
-
pageup: "PageUp",
|
|
323
|
-
esc: "Escape",
|
|
324
|
-
camera: "Camera",
|
|
325
|
-
delete: "Delete",
|
|
326
|
-
f1: "F1",
|
|
327
|
-
f2: "F2",
|
|
328
|
-
f3: "F3",
|
|
329
|
-
f4: "F4",
|
|
330
|
-
f5: "F5",
|
|
331
|
-
f6: "F6",
|
|
332
|
-
f7: "F7",
|
|
333
|
-
f8: "F8",
|
|
334
|
-
f9: "F9",
|
|
335
|
-
f10: "F10",
|
|
336
|
-
f11: "F11",
|
|
337
|
-
f12: "F12",
|
|
338
|
-
f13: "F13",
|
|
339
|
-
f14: "F14",
|
|
340
|
-
f15: "F15",
|
|
341
|
-
f16: "F16",
|
|
342
|
-
f17: "F17",
|
|
343
|
-
f18: "F18",
|
|
344
|
-
f19: "F19",
|
|
345
|
-
f20: "F20"
|
|
346
|
-
};
|
|
347
|
-
const toListenableKeycomboItems = createMap((name) => ({ name, type: fromComboItemNameToType(name) }));
|
|
348
|
-
function narrowKeycombo(type) {
|
|
349
|
-
return new Pipeable(type).pipe(
|
|
350
|
-
toCombo,
|
|
351
|
-
toListenableKeycomboItems
|
|
352
|
-
);
|
|
2115
|
+
function defineAsyncGraphEdges(edges) {
|
|
2116
|
+
return edges;
|
|
353
2117
|
}
|
|
354
|
-
function
|
|
355
|
-
return
|
|
2118
|
+
function defineAsyncGraphEdge(from, to, predicateTraversable) {
|
|
2119
|
+
return { from, to, predicateTraversable };
|
|
356
2120
|
}
|
|
357
|
-
|
|
358
|
-
|
|
2121
|
+
|
|
2122
|
+
function defineAssociativeArrayEntries(entries) {
|
|
2123
|
+
return entries;
|
|
359
2124
|
}
|
|
360
|
-
|
|
361
|
-
const toComboItems = map((name) => name === "" ? delimiter : name);
|
|
362
|
-
const delimiter = "+";
|
|
363
|
-
function toCombo(type) {
|
|
364
|
-
return pipe(
|
|
365
|
-
toUnique$1,
|
|
366
|
-
toComboItems,
|
|
367
|
-
toArray()
|
|
368
|
-
)(type.split(delimiter));
|
|
369
|
-
}
|
|
370
|
-
function fromComboItemNameToType(name) {
|
|
371
|
-
return find((type) => predicatesByType[type](name))(listenableComboItemTypes) ?? "custom";
|
|
372
|
-
}
|
|
373
|
-
const listenableComboItemTypes = /* @__PURE__ */ new Set(["singleCharacter", "arrow", "other", "modifier", "click", "pointer"]);
|
|
374
|
-
const predicatesByType = {
|
|
375
|
-
singleCharacter: (name) => typeREs["singleCharacter"].test(name),
|
|
376
|
-
arrow: (name) => typeREs["arrow"].test(name),
|
|
377
|
-
other: (name) => typeREs["other"].test(name),
|
|
378
|
-
modifier: (name) => typeREs["modifier"].test(name),
|
|
379
|
-
click: (name) => typeREs["click"].test(name),
|
|
380
|
-
pointer: (name) => typeREs["pointer"].test(name)
|
|
381
|
-
};
|
|
382
|
-
const typeREs = {
|
|
383
|
-
singleCharacter: /^!?[a-zA-Z0-9,<.>/?;:'"[{\]}\\|`~!@#$%^&*()-_=+]$/,
|
|
384
|
-
arrow: /^!?(arrow|vertical|horizontal|up|down|right|left)$/,
|
|
385
|
-
other: /^!?(enter|backspace|space|tab|esc|home|end|pagedown|pageup|capslock|f[0-9]{1,2}|camera|delete)$/,
|
|
386
|
-
modifier: /^!?(cmd|command|meta|shift|ctrl|control|alt|opt|option)$/,
|
|
387
|
-
click: /^!?(rightclick|contextmenu|click|mousedown|mouseup|dblclick)$/,
|
|
388
|
-
pointer: /^!?(pointerdown|pointerup|pointermove|pointerover|pointerout|pointerenter|pointerleave|pointercancel|gotpointercapture|lostpointercapture)$/
|
|
389
|
-
};
|
|
390
|
-
function toModifier(modifierOrAlias) {
|
|
391
|
-
return modifierOrAlias in modifiersByAlias ? modifiersByAlias[modifierOrAlias] : modifierOrAlias;
|
|
392
|
-
}
|
|
393
|
-
const modifiersByAlias = {
|
|
394
|
-
cmd: "meta",
|
|
395
|
-
command: "meta",
|
|
396
|
-
ctrl: "control",
|
|
397
|
-
opt: "alt",
|
|
398
|
-
option: "alt"
|
|
399
|
-
};
|
|
2125
|
+
|
|
400
2126
|
function createExceptAndOnlyEffect(type, effect, options) {
|
|
401
2127
|
const { except = [], only = [] } = options;
|
|
402
2128
|
if (type === "keydown" || type === "keyup") {
|
|
403
2129
|
return (event) => {
|
|
404
|
-
const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false,
|
|
2130
|
+
const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false, false];
|
|
405
2131
|
if (matchesOnly) {
|
|
406
2132
|
effect(event);
|
|
407
2133
|
return;
|
|
@@ -414,7 +2140,7 @@ function createExceptAndOnlyEffect(type, effect, options) {
|
|
|
414
2140
|
}
|
|
415
2141
|
if (type === "click" || type === "dblclick" || type === "contextmenu" || type.startsWith("mouse")) {
|
|
416
2142
|
return (event) => {
|
|
417
|
-
const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false,
|
|
2143
|
+
const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false, false];
|
|
418
2144
|
if (matchesOnly) {
|
|
419
2145
|
effect(event);
|
|
420
2146
|
return;
|
|
@@ -427,7 +2153,7 @@ function createExceptAndOnlyEffect(type, effect, options) {
|
|
|
427
2153
|
}
|
|
428
2154
|
if (type.startsWith("pointer")) {
|
|
429
2155
|
return (event) => {
|
|
430
|
-
const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false,
|
|
2156
|
+
const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false, false];
|
|
431
2157
|
if (matchesOnly) {
|
|
432
2158
|
effect(event);
|
|
433
2159
|
return;
|
|
@@ -439,7 +2165,7 @@ function createExceptAndOnlyEffect(type, effect, options) {
|
|
|
439
2165
|
};
|
|
440
2166
|
}
|
|
441
2167
|
return (event) => {
|
|
442
|
-
const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false,
|
|
2168
|
+
const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false, false];
|
|
443
2169
|
if (matchesOnly) {
|
|
444
2170
|
effect(event, {});
|
|
445
2171
|
return;
|
|
@@ -450,27 +2176,15 @@ function createExceptAndOnlyEffect(type, effect, options) {
|
|
|
450
2176
|
}
|
|
451
2177
|
};
|
|
452
2178
|
}
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
}
|
|
456
|
-
const predicatesByModifier = {
|
|
457
|
-
shift: (event) => event.shiftKey,
|
|
458
|
-
cmd: (event) => event.metaKey,
|
|
459
|
-
command: (event) => event.metaKey,
|
|
460
|
-
meta: (event) => event.metaKey,
|
|
461
|
-
ctrl: (event) => event.ctrlKey,
|
|
462
|
-
control: (event) => event.ctrlKey,
|
|
463
|
-
alt: (event) => event.altKey,
|
|
464
|
-
opt: (event) => event.altKey,
|
|
465
|
-
option: (event) => event.altKey
|
|
466
|
-
};
|
|
467
|
-
function domIsAvailable() {
|
|
2179
|
+
|
|
2180
|
+
function getDomAvailability() {
|
|
468
2181
|
try {
|
|
469
|
-
return !!window;
|
|
2182
|
+
return !!window ? "available" : "unavailable";
|
|
470
2183
|
} catch (error) {
|
|
471
|
-
return
|
|
2184
|
+
return "unavailable";
|
|
472
2185
|
}
|
|
473
2186
|
}
|
|
2187
|
+
|
|
474
2188
|
function predicateArray(value) {
|
|
475
2189
|
return Array.isArray(value);
|
|
476
2190
|
}
|
|
@@ -489,24 +2203,8 @@ function predicateNumber(value) {
|
|
|
489
2203
|
function predicateString(value) {
|
|
490
2204
|
return typeof value === "string";
|
|
491
2205
|
}
|
|
492
|
-
|
|
493
|
-
"
|
|
494
|
-
"select:not([disabled])",
|
|
495
|
-
"textarea:not([disabled])",
|
|
496
|
-
"button:not([disabled])",
|
|
497
|
-
"a[href]",
|
|
498
|
-
"area[href]",
|
|
499
|
-
"summary",
|
|
500
|
-
"iframe",
|
|
501
|
-
"object",
|
|
502
|
-
"embed",
|
|
503
|
-
"audio[controls]",
|
|
504
|
-
"video[controls]",
|
|
505
|
-
"[contenteditable]",
|
|
506
|
-
"[tabindex]:not([disabled])"
|
|
507
|
-
]);
|
|
508
|
-
function predicateFocusable(element) {
|
|
509
|
-
return element.matches(tabbableSelector);
|
|
2206
|
+
function predicateObject(value) {
|
|
2207
|
+
return typeof value === "object";
|
|
510
2208
|
}
|
|
511
2209
|
|
|
512
2210
|
class Recognizeable {
|
|
@@ -519,7 +2217,7 @@ class Recognizeable {
|
|
|
519
2217
|
effects: {}
|
|
520
2218
|
};
|
|
521
2219
|
this.maxSequenceLength = options?.maxSequenceLength || defaultOptions.maxSequenceLength;
|
|
522
|
-
this.effects =
|
|
2220
|
+
this.effects = options?.effects || defaultOptions.effects;
|
|
523
2221
|
this.resetComputedMetadata();
|
|
524
2222
|
this.setSequence(sequence);
|
|
525
2223
|
this.effectApi = {
|
|
@@ -528,8 +2226,6 @@ class Recognizeable {
|
|
|
528
2226
|
setMetadata: (metadata) => this.computedMetadata = metadata,
|
|
529
2227
|
recognized: () => this.recognized(),
|
|
530
2228
|
denied: () => this.denied(),
|
|
531
|
-
recognizedUntilReady: () => this.recognizedUntilReady(),
|
|
532
|
-
deniedUntilReady: () => this.deniedUntilReady(),
|
|
533
2229
|
ready: () => this.ready()
|
|
534
2230
|
};
|
|
535
2231
|
this.ready();
|
|
@@ -544,12 +2240,6 @@ class Recognizeable {
|
|
|
544
2240
|
denied() {
|
|
545
2241
|
this.computedStatus = "denied";
|
|
546
2242
|
}
|
|
547
|
-
recognizedUntilReady() {
|
|
548
|
-
this.computedStatus = "recognized until ready";
|
|
549
|
-
}
|
|
550
|
-
deniedUntilReady() {
|
|
551
|
-
this.computedStatus = "denied until ready";
|
|
552
|
-
}
|
|
553
2243
|
computedStatus;
|
|
554
2244
|
ready() {
|
|
555
2245
|
this.computedStatus = "ready";
|
|
@@ -572,8 +2262,7 @@ class Recognizeable {
|
|
|
572
2262
|
return this;
|
|
573
2263
|
}
|
|
574
2264
|
recognize(sequenceItem, { onRecognized } = {}) {
|
|
575
|
-
|
|
576
|
-
this.recognizing();
|
|
2265
|
+
this.recognizing();
|
|
577
2266
|
const type = this.toType(sequenceItem), excess = predicateNumber(this.maxSequenceLength) ? Math.max(0, this.sequence.length - this.maxSequenceLength) : 0, newSequence = createConcat(
|
|
578
2267
|
createSlice(excess)(this.sequence),
|
|
579
2268
|
[sequenceItem]
|
|
@@ -581,11 +2270,10 @@ class Recognizeable {
|
|
|
581
2270
|
this.effectApi.getSequence = () => newSequence;
|
|
582
2271
|
this.effectApi.onRecognized = onRecognized || (() => {
|
|
583
2272
|
});
|
|
584
|
-
this.effects
|
|
2273
|
+
this.effects[type]?.(sequenceItem, { ...this.effectApi });
|
|
585
2274
|
switch (this.status) {
|
|
586
2275
|
case "ready":
|
|
587
2276
|
case "denied":
|
|
588
|
-
case "denied until ready":
|
|
589
2277
|
this.resetComputedMetadata();
|
|
590
2278
|
this.setSequence([]);
|
|
591
2279
|
break;
|
|
@@ -628,8 +2316,8 @@ class Listenable {
|
|
|
628
2316
|
computedActive;
|
|
629
2317
|
constructor(type, options) {
|
|
630
2318
|
if (type === "recognizeable") {
|
|
631
|
-
this.computedRecognizeable = new Recognizeable([], options?.recognizeable
|
|
632
|
-
this.recognizeableEffectsKeys = Object.keys(options?.recognizeable?.effects
|
|
2319
|
+
this.computedRecognizeable = new Recognizeable([], options?.recognizeable);
|
|
2320
|
+
this.recognizeableEffectsKeys = Object.keys(options?.recognizeable?.effects);
|
|
633
2321
|
}
|
|
634
2322
|
this.computedActive = /* @__PURE__ */ new Set();
|
|
635
2323
|
this.setType(type);
|
|
@@ -729,24 +2417,10 @@ class Listenable {
|
|
|
729
2417
|
this.active.add({ target, id: [this.type, effect] });
|
|
730
2418
|
}
|
|
731
2419
|
recognizeableListen(effect, options) {
|
|
732
|
-
let effectStatus = "ready";
|
|
733
2420
|
const guardedEffect = (sequenceItem) => {
|
|
734
2421
|
this.recognizeable.recognize(sequenceItem, { onRecognized: (sequenceItem2) => effect(sequenceItem2) });
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
if (effectStatus === "ready") {
|
|
738
|
-
effect(sequenceItem);
|
|
739
|
-
effectStatus = "performed";
|
|
740
|
-
}
|
|
741
|
-
break;
|
|
742
|
-
case "recognized":
|
|
743
|
-
effect(sequenceItem);
|
|
744
|
-
effectStatus = "ready";
|
|
745
|
-
break;
|
|
746
|
-
default:
|
|
747
|
-
effectStatus = "ready";
|
|
748
|
-
break;
|
|
749
|
-
}
|
|
2422
|
+
if (this.recognizeable.status === "recognized")
|
|
2423
|
+
effect(sequenceItem);
|
|
750
2424
|
};
|
|
751
2425
|
for (const type of this.recognizeableEffectsKeys) {
|
|
752
2426
|
const listenable = new Listenable(type);
|
|
@@ -767,10 +2441,10 @@ class Listenable {
|
|
|
767
2441
|
}
|
|
768
2442
|
addEventListeners(eventListeners, options) {
|
|
769
2443
|
const { target = document } = options;
|
|
770
|
-
|
|
2444
|
+
for (const eventListener of eventListeners) {
|
|
771
2445
|
target.addEventListener(eventListener[0], eventListener[1], eventListener[2]);
|
|
772
2446
|
this.active.add({ target, id: eventListener });
|
|
773
|
-
}
|
|
2447
|
+
}
|
|
774
2448
|
}
|
|
775
2449
|
listening() {
|
|
776
2450
|
this.computedStatus = "listening";
|
|
@@ -882,109 +2556,22 @@ function toAddEventListenerParams(type, effect, options) {
|
|
|
882
2556
|
const { addEventListener, useCapture } = options, exceptAndOnlyEffect = createExceptAndOnlyEffect(type, effect, options), effectOptions = [addEventListener || useCapture];
|
|
883
2557
|
return { exceptAndOnlyEffect, effectOptions };
|
|
884
2558
|
}
|
|
885
|
-
function eventMatchesKeycombo(event, keycombo) {
|
|
886
|
-
return every(({ name, type }, index) => {
|
|
887
|
-
switch (type) {
|
|
888
|
-
case "singleCharacter":
|
|
889
|
-
if (name === "!")
|
|
890
|
-
return event.key === "!";
|
|
891
|
-
const keyToTest = event.altKey && fromComboItemNameToType(event.key) === "custom" ? fromCodeToSingleCharacter(event.code) : event.key.toLowerCase();
|
|
892
|
-
return name.startsWith("!") ? keyToTest !== toKey(name.slice(1)).toLowerCase() : keyToTest === toKey(name).toLowerCase();
|
|
893
|
-
case "other":
|
|
894
|
-
if (name === "!") {
|
|
895
|
-
return event.key === "!";
|
|
896
|
-
}
|
|
897
|
-
return name.startsWith("!") ? event.key.toLowerCase() !== toKey(name.slice(1)).toLowerCase() : event.key.toLowerCase() === toKey(name).toLowerCase();
|
|
898
|
-
case "arrow":
|
|
899
|
-
return predicatesByArrow.get(name)?.({ event, name }) ?? predicatesByArrow.get("default")({ event, name });
|
|
900
|
-
case "modifier":
|
|
901
|
-
if (index === keycombo.length - 1) {
|
|
902
|
-
return name.startsWith("!") ? event.key.toLowerCase() !== toModifier(name.slice(1)).toLowerCase() : event.key.toLowerCase() === toModifier(name).toLowerCase();
|
|
903
|
-
}
|
|
904
|
-
return name.startsWith("!") ? !predicateModified({ event, alias: name.slice(1) }) : predicateModified({ event, alias: name });
|
|
905
|
-
}
|
|
906
|
-
})(keycombo);
|
|
907
|
-
}
|
|
908
|
-
function fromCodeToSingleCharacter(code) {
|
|
909
|
-
for (const c in aliasesByCode) {
|
|
910
|
-
if (c === code) {
|
|
911
|
-
return aliasesByCode[c];
|
|
912
|
-
}
|
|
913
|
-
}
|
|
914
|
-
for (const prefix of ["Key", "Digit"]) {
|
|
915
|
-
const re = new RegExp(`^${prefix}`);
|
|
916
|
-
if (re.test(code)) {
|
|
917
|
-
return createClip(re)(code).toLowerCase();
|
|
918
|
-
}
|
|
919
|
-
}
|
|
920
|
-
return code;
|
|
921
|
-
}
|
|
922
|
-
const aliasesByCode = {
|
|
923
|
-
"Backquote": "`",
|
|
924
|
-
"Minus": "-",
|
|
925
|
-
"Equal": "=",
|
|
926
|
-
"BracketLeft": "[",
|
|
927
|
-
"BracketRight": "]",
|
|
928
|
-
"Backslash": "\\",
|
|
929
|
-
"Semicolon": ";",
|
|
930
|
-
"Quote": "'",
|
|
931
|
-
"Comma": ",",
|
|
932
|
-
"Period": ".",
|
|
933
|
-
"Slash": "/"
|
|
934
|
-
};
|
|
935
|
-
const predicatesByArrow = /* @__PURE__ */ new Map([
|
|
936
|
-
[
|
|
937
|
-
"arrow",
|
|
938
|
-
({ event }) => arrows.has(event.key.toLowerCase())
|
|
939
|
-
],
|
|
940
|
-
[
|
|
941
|
-
"!arrow",
|
|
942
|
-
({ event }) => !arrows.has(event.key.toLowerCase())
|
|
943
|
-
],
|
|
944
|
-
[
|
|
945
|
-
"vertical",
|
|
946
|
-
({ event }) => verticalArrows.has(event.key.toLowerCase())
|
|
947
|
-
],
|
|
948
|
-
[
|
|
949
|
-
"!vertical",
|
|
950
|
-
({ event }) => !verticalArrows.has(event.key.toLowerCase())
|
|
951
|
-
],
|
|
952
|
-
[
|
|
953
|
-
"horizontal",
|
|
954
|
-
({ event }) => horizontalArrows.has(event.key.toLowerCase())
|
|
955
|
-
],
|
|
956
|
-
[
|
|
957
|
-
"!horizontal",
|
|
958
|
-
({ event }) => !horizontalArrows.has(event.key.toLowerCase())
|
|
959
|
-
],
|
|
960
|
-
[
|
|
961
|
-
"default",
|
|
962
|
-
({ event, name }) => name.startsWith("!") ? event.key.toLowerCase() !== `arrow${name.toLowerCase()}` : event.key.toLowerCase() === `arrow${name.toLowerCase()}`
|
|
963
|
-
]
|
|
964
|
-
]);
|
|
965
|
-
const arrows = /* @__PURE__ */ new Set(["arrowup", "arrowright", "arrowdown", "arrowleft"]);
|
|
966
|
-
const verticalArrows = /* @__PURE__ */ new Set(["arrowup", "arrowdown"]);
|
|
967
|
-
const horizontalArrows = /* @__PURE__ */ new Set(["arrowright", "arrowleft"]);
|
|
968
|
-
function eventMatchesMousecombo(event, Mousecombo) {
|
|
969
|
-
return every((name) => fromComboItemNameToType(name) === "click" || name.startsWith("!") && !predicateModified({ alias: name.slice(1), event }) || !name.startsWith("!") && predicateModified({ alias: name, event }))(Mousecombo);
|
|
970
|
-
}
|
|
971
|
-
function eventMatchesPointercombo(event, pointercombo) {
|
|
972
|
-
return every((name) => fromComboItemNameToType(name) === "pointer" || name.startsWith("!") && !predicateModified({ alias: name.slice(1), event }) || !name.startsWith("!") && predicateModified({ alias: name, event }))(pointercombo);
|
|
973
|
-
}
|
|
974
2559
|
const observerAssertionsByType = {
|
|
975
2560
|
intersect: (observer) => observer instanceof IntersectionObserver,
|
|
976
2561
|
mutate: (observer) => observer instanceof MutationObserver,
|
|
977
2562
|
resize: (observer) => observer instanceof ResizeObserver
|
|
978
2563
|
};
|
|
979
2564
|
|
|
980
|
-
const defaultOptions$
|
|
2565
|
+
const defaultOptions$8 = {
|
|
981
2566
|
duration: 0,
|
|
2567
|
+
// delay not supported, because it can be effectd by delayable
|
|
982
2568
|
timing: [
|
|
983
2569
|
0,
|
|
984
2570
|
0,
|
|
985
2571
|
1,
|
|
986
2572
|
1
|
|
987
2573
|
],
|
|
2574
|
+
// linear by default
|
|
988
2575
|
iterations: 1,
|
|
989
2576
|
alternates: false
|
|
990
2577
|
};
|
|
@@ -1005,10 +2592,10 @@ class Animateable {
|
|
|
1005
2592
|
getEaseables;
|
|
1006
2593
|
getReversedEaseables;
|
|
1007
2594
|
constructor(keyframes, options = {}) {
|
|
1008
|
-
this.initialDuration = options?.duration || defaultOptions$
|
|
1009
|
-
this.controlPoints = fromTimingToControlPoints(options?.timing || defaultOptions$
|
|
1010
|
-
this.iterationLimit = options?.iterations || defaultOptions$
|
|
1011
|
-
this.alternates = options?.alternates || defaultOptions$
|
|
2595
|
+
this.initialDuration = options?.duration || defaultOptions$8.duration;
|
|
2596
|
+
this.controlPoints = fromTimingToControlPoints(options?.timing || defaultOptions$8.timing);
|
|
2597
|
+
this.iterationLimit = options?.iterations || defaultOptions$8.iterations;
|
|
2598
|
+
this.alternates = options?.alternates || defaultOptions$8.alternates;
|
|
1012
2599
|
this.reversedControlPoints = fromControlPointsToReversedControlPoints(this.controlPoints);
|
|
1013
2600
|
this.toAnimationProgress = createToAnimationProgress(this.controlPoints);
|
|
1014
2601
|
this.reversedToAnimationProgress = createToAnimationProgress(this.reversedControlPoints);
|
|
@@ -1084,10 +2671,11 @@ class Animateable {
|
|
|
1084
2671
|
setKeyframes(keyframes) {
|
|
1085
2672
|
this.stop();
|
|
1086
2673
|
this.computedKeyframes = Array.from(keyframes).sort(({ progress: progressA }, { progress: progressB }) => progressA - progressB);
|
|
1087
|
-
this.reversedKeyframes =
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
2674
|
+
this.reversedKeyframes = pipe(
|
|
2675
|
+
reverse$1(),
|
|
2676
|
+
map(({ progress, properties }) => ({ progress: 1 - progress, properties })),
|
|
2677
|
+
toArray()
|
|
2678
|
+
)(this.keyframes);
|
|
1091
2679
|
this.properties = toProperties(this.keyframes);
|
|
1092
2680
|
this.easeables = this.getEaseables({ keyframes: this.keyframes, properties: this.properties });
|
|
1093
2681
|
this.reversedEaseables = this.getReversedEaseables({ keyframes: this.reversedKeyframes, properties: this.properties });
|
|
@@ -1385,7 +2973,7 @@ class Animateable {
|
|
|
1385
2973
|
break;
|
|
1386
2974
|
case "reversing":
|
|
1387
2975
|
this.computedIterations += 1;
|
|
1388
|
-
if (this.
|
|
2976
|
+
if (this.iterationLimit === true || this.iterations < this.iterationLimit) {
|
|
1389
2977
|
this.createAnimate("reverse")(effect, options);
|
|
1390
2978
|
} else {
|
|
1391
2979
|
this.alternateCache.status = "ready";
|
|
@@ -1394,7 +2982,7 @@ class Animateable {
|
|
|
1394
2982
|
}
|
|
1395
2983
|
} else {
|
|
1396
2984
|
this.computedIterations += 1;
|
|
1397
|
-
if (this.
|
|
2985
|
+
if (this.iterationLimit === true || this.iterations < this.iterationLimit) {
|
|
1398
2986
|
this.createAnimate("play")(effect, options);
|
|
1399
2987
|
}
|
|
1400
2988
|
}
|
|
@@ -1410,7 +2998,7 @@ class Animateable {
|
|
|
1410
2998
|
switch (this.alternateCache.status) {
|
|
1411
2999
|
case "playing":
|
|
1412
3000
|
this.computedIterations += 1;
|
|
1413
|
-
if (this.
|
|
3001
|
+
if (this.iterationLimit === true || this.iterations < this.iterationLimit) {
|
|
1414
3002
|
this.createAnimate("play")(effect, options);
|
|
1415
3003
|
} else {
|
|
1416
3004
|
this.alternateCache.status = "ready";
|
|
@@ -1422,7 +3010,7 @@ class Animateable {
|
|
|
1422
3010
|
}
|
|
1423
3011
|
} else {
|
|
1424
3012
|
this.computedIterations += 1;
|
|
1425
|
-
if (this.iterations < this.iterationLimit) {
|
|
3013
|
+
if (this.iterationLimit === true || this.iterations < this.iterationLimit) {
|
|
1426
3014
|
this.createAnimate("reverse")(effect, options);
|
|
1427
3015
|
}
|
|
1428
3016
|
}
|
|
@@ -1631,7 +3219,7 @@ function createGetEaseables(fromKeyframeToControlPoints) {
|
|
|
1631
3219
|
(easeables, property) => {
|
|
1632
3220
|
const propertyKeyframes = createFilter(({ properties: properties2 }) => properties2.hasOwnProperty(property))(keyframes), fromKeyframesToEaseables = createReduce(
|
|
1633
3221
|
(propertyEaseables2, keyframe, index) => {
|
|
1634
|
-
const previous = keyframe.properties[property], next = index === propertyKeyframes.length - 1 ? previous : propertyKeyframes[index + 1].properties[property], start = keyframe.progress, end = index === propertyKeyframes.length - 1 ? 2 : propertyKeyframes[index + 1].progress, hasCustomTiming = !!keyframe.timing, toAnimationProgress = index === propertyKeyframes.length - 1 ? (
|
|
3222
|
+
const previous = keyframe.properties[property], next = index === propertyKeyframes.length - 1 ? previous : propertyKeyframes[index + 1].properties[property], start = keyframe.progress, end = index === propertyKeyframes.length - 1 ? 2 : propertyKeyframes[index + 1].progress, hasCustomTiming = !!keyframe.timing, toAnimationProgress = index === propertyKeyframes.length - 1 ? () => 1 : createToAnimationProgress(fromKeyframeToControlPoints({ keyframe, index, propertyKeyframes }));
|
|
1635
3223
|
propertyEaseables2.push({
|
|
1636
3224
|
property,
|
|
1637
3225
|
value: { previous, next },
|
|
@@ -1646,7 +3234,7 @@ function createGetEaseables(fromKeyframeToControlPoints) {
|
|
|
1646
3234
|
property,
|
|
1647
3235
|
value: { previous: propertyEaseables[0].value.previous, next: propertyEaseables[0].value.previous },
|
|
1648
3236
|
progress: { start: -1, end: propertyEaseables[0].progress.start },
|
|
1649
|
-
toAnimationProgress: (
|
|
3237
|
+
toAnimationProgress: () => 1,
|
|
1650
3238
|
hasCustomTiming: false
|
|
1651
3239
|
};
|
|
1652
3240
|
return createConcat(
|
|
@@ -1891,14 +3479,14 @@ const easingsNetInOutBack = [
|
|
|
1891
3479
|
1.6
|
|
1892
3480
|
];
|
|
1893
3481
|
|
|
1894
|
-
const defaultOptions$
|
|
3482
|
+
const defaultOptions$7 = {
|
|
1895
3483
|
name: "baleada"
|
|
1896
3484
|
};
|
|
1897
3485
|
class Broadcastable {
|
|
1898
3486
|
name;
|
|
1899
3487
|
constructor(state, options = {}) {
|
|
1900
3488
|
this.setState(state);
|
|
1901
|
-
this.name = options.name ?? defaultOptions$
|
|
3489
|
+
this.name = options.name ?? defaultOptions$7.name;
|
|
1902
3490
|
this.ready();
|
|
1903
3491
|
}
|
|
1904
3492
|
computedStatus;
|
|
@@ -1963,12 +3551,69 @@ function toMessageListenParams(instance, effect) {
|
|
|
1963
3551
|
];
|
|
1964
3552
|
}
|
|
1965
3553
|
|
|
3554
|
+
const defaultOptions$6 = {
|
|
3555
|
+
locales: "en",
|
|
3556
|
+
collator: { sensitivity: "base" }
|
|
3557
|
+
};
|
|
3558
|
+
class Compareable {
|
|
3559
|
+
constructor(string, options = {}) {
|
|
3560
|
+
const locales = options.locales || defaultOptions$6.locales, collatorOptions = { ...defaultOptions$6.collator, ...options.collator }, key = locales + pipe(
|
|
3561
|
+
createEntries(),
|
|
3562
|
+
sort((a, b) => a[0] < b[0] ? -1 : 1),
|
|
3563
|
+
join()
|
|
3564
|
+
)(collatorOptions);
|
|
3565
|
+
this.computedCollator = cache[key] || (cache[key] = new Intl.Collator(locales, collatorOptions));
|
|
3566
|
+
this.setString(string);
|
|
3567
|
+
this.ready();
|
|
3568
|
+
}
|
|
3569
|
+
computedStatus;
|
|
3570
|
+
ready() {
|
|
3571
|
+
this.computedStatus = "ready";
|
|
3572
|
+
}
|
|
3573
|
+
get string() {
|
|
3574
|
+
return this.computedString;
|
|
3575
|
+
}
|
|
3576
|
+
set string(string) {
|
|
3577
|
+
this.setString(string);
|
|
3578
|
+
}
|
|
3579
|
+
get status() {
|
|
3580
|
+
return this.computedStatus;
|
|
3581
|
+
}
|
|
3582
|
+
computedCollator;
|
|
3583
|
+
get collator() {
|
|
3584
|
+
return this.computedCollator;
|
|
3585
|
+
}
|
|
3586
|
+
computedComparison;
|
|
3587
|
+
get comparison() {
|
|
3588
|
+
return this.computedComparison;
|
|
3589
|
+
}
|
|
3590
|
+
computedString;
|
|
3591
|
+
setString(string) {
|
|
3592
|
+
this.computedString = string;
|
|
3593
|
+
return this;
|
|
3594
|
+
}
|
|
3595
|
+
compare(compared) {
|
|
3596
|
+
this.comparing();
|
|
3597
|
+
this.computedComparison = this.computedCollator.compare(this.string, compared);
|
|
3598
|
+
this.compared();
|
|
3599
|
+
return this;
|
|
3600
|
+
}
|
|
3601
|
+
comparing() {
|
|
3602
|
+
this.computedStatus = "comparing";
|
|
3603
|
+
}
|
|
3604
|
+
compared() {
|
|
3605
|
+
this.computedStatus = "compared";
|
|
3606
|
+
}
|
|
3607
|
+
}
|
|
3608
|
+
const cache = {};
|
|
3609
|
+
|
|
1966
3610
|
const defaultOptions$5 = {
|
|
1967
3611
|
segment: {
|
|
1968
3612
|
from: "start",
|
|
1969
3613
|
to: "end"
|
|
1970
3614
|
},
|
|
1971
3615
|
divider: /\s/
|
|
3616
|
+
// Keep an eye out for use cases where a { before, after } object would be needed, or where multi-character dividers need to be used
|
|
1972
3617
|
};
|
|
1973
3618
|
const defaultCompleteOptions = {
|
|
1974
3619
|
select: "completionEnd"
|
|
@@ -2051,6 +3696,7 @@ class Completeable {
|
|
|
2051
3696
|
}
|
|
2052
3697
|
return this;
|
|
2053
3698
|
}
|
|
3699
|
+
// TODO: Support array of selections for multi cursor editing
|
|
2054
3700
|
computedSelection;
|
|
2055
3701
|
setSelection(selection) {
|
|
2056
3702
|
this.computedSelection = selection;
|
|
@@ -2127,12 +3773,12 @@ function toPreviousMatch({ string, re, from }) {
|
|
|
2127
3773
|
if (!re.test(string.slice(0, from)) || from === 0) {
|
|
2128
3774
|
indexOf = -1;
|
|
2129
3775
|
} else {
|
|
2130
|
-
const reversedStringBeforeFrom =
|
|
3776
|
+
const reversedStringBeforeFrom = pipe(
|
|
2131
3777
|
(string2) => string2.slice(0, from),
|
|
2132
3778
|
(sliced) => sliced.split(""),
|
|
2133
3779
|
reverse,
|
|
2134
3780
|
toString
|
|
2135
|
-
), toNextMatchIndex = toNextMatch({ string: reversedStringBeforeFrom, re, from: 0 });
|
|
3781
|
+
)(string), toNextMatchIndex = toNextMatch({ string: reversedStringBeforeFrom, re, from: 0 });
|
|
2136
3782
|
indexOf = toNextMatchIndex === -1 ? -1 : reversedStringBeforeFrom.length - 1 - toNextMatchIndex;
|
|
2137
3783
|
}
|
|
2138
3784
|
return indexOf;
|
|
@@ -2503,11 +4149,12 @@ class Fetchable {
|
|
|
2503
4149
|
computedText;
|
|
2504
4150
|
constructor(resource, options = {}) {
|
|
2505
4151
|
this.setResource(resource);
|
|
2506
|
-
this.
|
|
2507
|
-
this.
|
|
2508
|
-
this.
|
|
2509
|
-
this.
|
|
2510
|
-
this.
|
|
4152
|
+
this.computedKy = ky.create(narrowOptions(options.ky));
|
|
4153
|
+
this.computedArrayBuffer = new Resolveable(async () => "arrayBuffer" in this.response ? await this.response.arrayBuffer() : void 0);
|
|
4154
|
+
this.computedBlob = new Resolveable(async () => "blob" in this.response ? await this.response.blob() : void 0);
|
|
4155
|
+
this.computedFormData = new Resolveable(async () => "formData" in this.response ? await this.response.formData() : void 0);
|
|
4156
|
+
this.computedJson = new Resolveable(async () => "json" in this.response ? await this.response.json() : void 0);
|
|
4157
|
+
this.computedText = new Resolveable(async () => "text" in this.response ? await this.response.text() : void 0);
|
|
2511
4158
|
this.ready();
|
|
2512
4159
|
}
|
|
2513
4160
|
computedStatus;
|
|
@@ -2520,6 +4167,10 @@ class Fetchable {
|
|
|
2520
4167
|
set resource(resource) {
|
|
2521
4168
|
this.setResource(resource);
|
|
2522
4169
|
}
|
|
4170
|
+
computedKy;
|
|
4171
|
+
get ky() {
|
|
4172
|
+
return this.computedKy;
|
|
4173
|
+
}
|
|
2523
4174
|
computedAbortController;
|
|
2524
4175
|
get abortController() {
|
|
2525
4176
|
if (!this.computedAbortController) {
|
|
@@ -2533,6 +4184,10 @@ class Fetchable {
|
|
|
2533
4184
|
get response() {
|
|
2534
4185
|
return this.computedResponse;
|
|
2535
4186
|
}
|
|
4187
|
+
computedRetryCount = 0;
|
|
4188
|
+
get retryCount() {
|
|
4189
|
+
return this.computedRetryCount;
|
|
4190
|
+
}
|
|
2536
4191
|
get error() {
|
|
2537
4192
|
return this.computedError;
|
|
2538
4193
|
}
|
|
@@ -2561,7 +4216,23 @@ class Fetchable {
|
|
|
2561
4216
|
async fetch(options = {}) {
|
|
2562
4217
|
this.fetching();
|
|
2563
4218
|
try {
|
|
2564
|
-
this.computedResponse = await
|
|
4219
|
+
this.computedResponse = await this.ky(
|
|
4220
|
+
this.resource,
|
|
4221
|
+
{
|
|
4222
|
+
...options,
|
|
4223
|
+
signal: this.abortController.signal,
|
|
4224
|
+
hooks: {
|
|
4225
|
+
...options.hooks,
|
|
4226
|
+
beforeRetry: [
|
|
4227
|
+
...options.hooks?.beforeRetry || [],
|
|
4228
|
+
({ retryCount }) => {
|
|
4229
|
+
this.retrying();
|
|
4230
|
+
this.computedRetryCount = retryCount;
|
|
4231
|
+
}
|
|
4232
|
+
]
|
|
4233
|
+
}
|
|
4234
|
+
}
|
|
4235
|
+
);
|
|
2565
4236
|
this.fetched();
|
|
2566
4237
|
} catch (error) {
|
|
2567
4238
|
this.computedError = error;
|
|
@@ -2575,6 +4246,9 @@ class Fetchable {
|
|
|
2575
4246
|
fetching() {
|
|
2576
4247
|
this.computedStatus = "fetching";
|
|
2577
4248
|
}
|
|
4249
|
+
retrying() {
|
|
4250
|
+
this.computedStatus = "retrying";
|
|
4251
|
+
}
|
|
2578
4252
|
fetched() {
|
|
2579
4253
|
this.computedStatus = "fetched";
|
|
2580
4254
|
}
|
|
@@ -2585,23 +4259,27 @@ class Fetchable {
|
|
|
2585
4259
|
this.computedStatus = "errored";
|
|
2586
4260
|
}
|
|
2587
4261
|
async get(options = {}) {
|
|
2588
|
-
await this.fetch({ signal: this.abortController.signal, ...
|
|
4262
|
+
await this.fetch({ signal: this.abortController.signal, ...options, method: "get" });
|
|
2589
4263
|
return this;
|
|
2590
4264
|
}
|
|
2591
4265
|
async patch(options = {}) {
|
|
2592
|
-
await this.fetch({ signal: this.abortController.signal, ...
|
|
4266
|
+
await this.fetch({ signal: this.abortController.signal, ...options, method: "patch" });
|
|
2593
4267
|
return this;
|
|
2594
4268
|
}
|
|
2595
4269
|
async post(options = {}) {
|
|
2596
|
-
await this.fetch({ signal: this.abortController.signal, ...
|
|
4270
|
+
await this.fetch({ signal: this.abortController.signal, ...options, method: "post" });
|
|
2597
4271
|
return this;
|
|
2598
4272
|
}
|
|
2599
4273
|
async put(options = {}) {
|
|
2600
|
-
await this.fetch({ signal: this.abortController.signal, ...
|
|
4274
|
+
await this.fetch({ signal: this.abortController.signal, ...options, method: "put" });
|
|
2601
4275
|
return this;
|
|
2602
4276
|
}
|
|
2603
4277
|
async delete(options = {}) {
|
|
2604
|
-
await this.fetch({ signal: this.abortController.signal, ...
|
|
4278
|
+
await this.fetch({ signal: this.abortController.signal, ...options, method: "delete" });
|
|
4279
|
+
return this;
|
|
4280
|
+
}
|
|
4281
|
+
async head(options = {}) {
|
|
4282
|
+
await this.fetch({ signal: this.abortController.signal, ...options, method: "head" });
|
|
2605
4283
|
return this;
|
|
2606
4284
|
}
|
|
2607
4285
|
abort() {
|
|
@@ -2610,16 +4288,9 @@ class Fetchable {
|
|
|
2610
4288
|
}
|
|
2611
4289
|
}
|
|
2612
4290
|
function narrowOptions(options) {
|
|
2613
|
-
|
|
2614
|
-
}
|
|
2615
|
-
|
|
2616
|
-
return {
|
|
2617
|
-
body: JSON.stringify(data),
|
|
2618
|
-
headers: {
|
|
2619
|
-
"Accept": "application/json",
|
|
2620
|
-
"Content-Type": "application/json"
|
|
2621
|
-
}
|
|
2622
|
-
};
|
|
4291
|
+
if (!options)
|
|
4292
|
+
return {};
|
|
4293
|
+
return predicateFunction(options) ? options({ stop: ky.stop }) : options;
|
|
2623
4294
|
}
|
|
2624
4295
|
|
|
2625
4296
|
class Fullscreenable {
|
|
@@ -2947,13 +4618,12 @@ class Pickable {
|
|
|
2947
4618
|
}
|
|
2948
4619
|
pick(indexOrIndices, options = {}) {
|
|
2949
4620
|
const { replace, allowsDuplicates } = { ...defaultPickOptions, ...options };
|
|
2950
|
-
this.computedPicks =
|
|
4621
|
+
this.computedPicks = pipe(
|
|
2951
4622
|
narrowIndices,
|
|
2952
4623
|
this.toPossiblePicks,
|
|
2953
4624
|
(possiblePicks) => {
|
|
2954
|
-
if (replace === "all")
|
|
4625
|
+
if (replace === "all")
|
|
2955
4626
|
return allowsDuplicates ? possiblePicks : toUnique(possiblePicks);
|
|
2956
|
-
}
|
|
2957
4627
|
const maybeWithoutDuplicates = allowsDuplicates ? possiblePicks : createFilter(
|
|
2958
4628
|
(possiblePick) => typeof find((pick) => pick === possiblePick)(this.picks || []) !== "number"
|
|
2959
4629
|
)(possiblePicks);
|
|
@@ -2970,10 +4640,11 @@ class Pickable {
|
|
|
2970
4640
|
if (maybeWithoutDuplicates.length > this.picks.length) {
|
|
2971
4641
|
return createSlice(maybeWithoutDuplicates.length - this.picks.length)(maybeWithoutDuplicates);
|
|
2972
4642
|
}
|
|
2973
|
-
return
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
4643
|
+
return pipe(
|
|
4644
|
+
slice(maybeWithoutDuplicates.length),
|
|
4645
|
+
(array) => concat(array, maybeWithoutDuplicates),
|
|
4646
|
+
toArray()
|
|
4647
|
+
)(this.picks);
|
|
2977
4648
|
case "lifo":
|
|
2978
4649
|
if (maybeWithoutDuplicates.length === 0) {
|
|
2979
4650
|
return this.picks;
|
|
@@ -2984,13 +4655,14 @@ class Pickable {
|
|
|
2984
4655
|
if (maybeWithoutDuplicates.length > this.picks.length) {
|
|
2985
4656
|
return createSlice(0, maybeWithoutDuplicates.length - this.picks.length + 1)(maybeWithoutDuplicates);
|
|
2986
4657
|
}
|
|
2987
|
-
return
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
4658
|
+
return pipe(
|
|
4659
|
+
slice(0, this.picks.length - maybeWithoutDuplicates.length - 1),
|
|
4660
|
+
(array) => concat(array, maybeWithoutDuplicates),
|
|
4661
|
+
toArray()
|
|
4662
|
+
)(this.picks);
|
|
2991
4663
|
}
|
|
2992
4664
|
}
|
|
2993
|
-
);
|
|
4665
|
+
)(indexOrIndices);
|
|
2994
4666
|
this.computedFirst = Math.min(...this.picks);
|
|
2995
4667
|
this.computedLast = Math.max(...this.picks);
|
|
2996
4668
|
this.computedMultiple = toUnique(this.picks).length > 1;
|
|
@@ -3038,7 +4710,7 @@ class Sanitizeable {
|
|
|
3038
4710
|
computedDompurify;
|
|
3039
4711
|
computedStatus;
|
|
3040
4712
|
ready() {
|
|
3041
|
-
if (
|
|
4713
|
+
if (getDomAvailability() === "available") {
|
|
3042
4714
|
this.computedDompurify = createDOMPurify();
|
|
3043
4715
|
this.computedDompurify.setConfig(this.domPurifyConfig);
|
|
3044
4716
|
}
|
|
@@ -3051,7 +4723,7 @@ class Sanitizeable {
|
|
|
3051
4723
|
this.setHtml(html);
|
|
3052
4724
|
}
|
|
3053
4725
|
get dompurify() {
|
|
3054
|
-
if (!this.computedDompurify &&
|
|
4726
|
+
if (!this.computedDompurify && getDomAvailability() === "available") {
|
|
3055
4727
|
this.computedDompurify = createDOMPurify();
|
|
3056
4728
|
this.computedDompurify.setConfig(this.domPurifyConfig);
|
|
3057
4729
|
}
|
|
@@ -3194,7 +4866,7 @@ class Storeable {
|
|
|
3194
4866
|
computedStatus;
|
|
3195
4867
|
ready() {
|
|
3196
4868
|
this.computedStatus = "ready";
|
|
3197
|
-
if (
|
|
4869
|
+
if (getDomAvailability() === "available") {
|
|
3198
4870
|
if (predicateNull(this.storage.getItem(this.computedStatusKey))) {
|
|
3199
4871
|
this.storeStatus();
|
|
3200
4872
|
}
|
|
@@ -3207,7 +4879,7 @@ class Storeable {
|
|
|
3207
4879
|
this.setKey(key);
|
|
3208
4880
|
}
|
|
3209
4881
|
get status() {
|
|
3210
|
-
if (
|
|
4882
|
+
if (getDomAvailability() === "available") {
|
|
3211
4883
|
const storedStatus = this.storage.getItem(this.computedStatusKey);
|
|
3212
4884
|
if (this.computedStatus !== storedStatus && predicateString(storedStatus)) {
|
|
3213
4885
|
this.computedStatus = storedStatus;
|
|
@@ -3295,4 +4967,4 @@ class Storeable {
|
|
|
3295
4967
|
}
|
|
3296
4968
|
}
|
|
3297
4969
|
|
|
3298
|
-
export { Animateable, Broadcastable, Completeable, Copyable, Delayable, Drawable, Fetchable, Fullscreenable, Grantable, Listenable, Navigateable, Pickable,
|
|
4970
|
+
export { Animateable, Broadcastable, Compareable, Completeable, Copyable, Delayable, Drawable, Fetchable, Fullscreenable, Grantable, Listenable, Navigateable, Pickable, Recognizeable, Resolveable, Sanitizeable, Searchable, Shareable, Storeable, createAssociativeArray, createPredicateAncestor$1 as createAsyncDirectedAcyclicPredicateAncestor, createToCommonAncestors$1 as createAsyncDirectedAcyclicToCommonAncestors, createToLayers as createAsyncDirectedAcyclicToLayers, createToNodeSteps$1 as createAsyncDirectedAcyclicToNodeSteps, createToPath$1 as createAsyncDirectedAcyclicToPath, createToSteps$1 as createAsyncDirectedAcyclicToSteps, createToTree$1 as createAsyncDirectedAcyclicToTree, createClamp, createClip, createClone, createConcat, createPredicateAncestor as createDecisionTreePredicateAncestor, createToCommonAncestors as createDecisionTreeToCommonAncestors, createToNodeSteps as createDecisionTreeToNodeSteps, createToPath as createDecisionTreeToPath, createToSteps as createDecisionTreeToSteps, createToTree as createDecisionTreeToTree, createDetermine, createPredicateAncestor$2 as createDirectedAcyclicPredicateAncestor, createToCommonAncestors$2 as createDirectedAcyclicToCommonAncestors, createToLayers$1 as createDirectedAcyclicToLayers, createToNodeSteps$2 as createDirectedAcyclicToNodeSteps, createToPath$2 as createDirectedAcyclicToPath, createToRoots as createDirectedAcyclicToRoots, createToSteps$2 as createDirectedAcyclicToSteps, createToTree$2 as createDirectedAcyclicToTree, createEntries, createEqual, createEvery, createFilter, createFilterAsync, createFindAsync, createFindIndexAsync, createFocusable, createForEachAsync, createInsert, createKeychord, createKeypress, createKeyrelease, createKeys, createKonami, createList, createMap, createMapAsync, createMousepress, createMouserelease, createPredicateKeycomboMatch$1 as createPredicateKeycomboMatch, createPredicateRoot, createReduce, createReduceAsync, createRemove, createRename, createReorder, createReplace, createReverse, createSlice, createSlug, createSome, createSort, createSwap, createToGraph, createToIncoming, createToIndegree, createToOutdegree, createToOutgoing, createTouchpress, createTouchrelease, createFind as createTreeFind, createUnique, defineAssociativeArrayEntries, defineAsyncGraph, defineAsyncGraphEdge, defineAsyncGraphEdges, defineGraph, defineGraphEdge, defineGraphEdges, defineGraphNode, defineGraphNodes, easingsNetInBack, easingsNetInCirc, easingsNetInCubic, easingsNetInExpo, easingsNetInOutBack, easingsNetInOutCirc, easingsNetInOutCubic, easingsNetInOutExpo, easingsNetInOutQuad, easingsNetInOutQuint, easingsNetInOutSine, easingsNetInQuad, easingsNetInQuart, easingsNetInQuint, easingsNetInSine, easingsNetOutBack, easingsNetOutCirc, easingsNetOutCubic, easingsNetOutExpo, easingsNetOutQuad, easingsNetOutQuint, easingsNetOutSine, linear, materialAccelerated, materialDecelerated, materialStandard, toD, toFlattenedD, toMessageListenParams, verouEase, verouEaseIn, verouEaseInOut, verouEaseOut };
|