@baleada/logic 0.22.7 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.cjs +2224 -508
- package/lib/index.d.ts +507 -73
- package/lib/index.js +2168 -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,1986 @@ 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
|
+
const defaultOptions$f = {
|
|
1261
|
+
minDuration: 0,
|
|
1262
|
+
minDistance: 0,
|
|
1263
|
+
getMousemoveTarget: (event) => event.target
|
|
1264
|
+
};
|
|
1265
|
+
function createMousepress(options = {}) {
|
|
1266
|
+
const {
|
|
1267
|
+
minDuration,
|
|
1268
|
+
minDistance,
|
|
1269
|
+
getMousemoveTarget,
|
|
1270
|
+
onDown,
|
|
1271
|
+
onLeave,
|
|
1272
|
+
onMove,
|
|
1273
|
+
onUp
|
|
1274
|
+
} = { ...defaultOptions$f, ...options }, cleanup = (event) => {
|
|
1275
|
+
window.cancelAnimationFrame(request);
|
|
1276
|
+
getMousemoveTarget(event).removeEventListener("mousemove", mousemoveEffect);
|
|
1277
|
+
};
|
|
1278
|
+
let request;
|
|
1279
|
+
let mousemoveEffect;
|
|
1280
|
+
let mouseStatus;
|
|
1281
|
+
const mousedown = (event, api) => {
|
|
1282
|
+
mouseStatus = "down";
|
|
1283
|
+
mousemoveEffect = (event2) => mousemove(event2, api);
|
|
1284
|
+
storePointerStartMetadata(event, api);
|
|
1285
|
+
storePointerMoveMetadata(event, api);
|
|
1286
|
+
storePointerTimeMetadata(
|
|
1287
|
+
event,
|
|
1288
|
+
api,
|
|
1289
|
+
() => mouseStatus === "down",
|
|
1290
|
+
(newRequest) => request = newRequest,
|
|
1291
|
+
recognize
|
|
1292
|
+
);
|
|
1293
|
+
getMousemoveTarget(event).addEventListener("mousemove", mousemoveEffect);
|
|
1294
|
+
onDown?.(toHookApi(api));
|
|
1295
|
+
};
|
|
1296
|
+
const mousemove = (event, api) => {
|
|
1297
|
+
storePointerMoveMetadata(event, api);
|
|
1298
|
+
recognize(event, api);
|
|
1299
|
+
onMove?.(toHookApi(api));
|
|
1300
|
+
};
|
|
1301
|
+
const recognize = (event, api) => {
|
|
1302
|
+
const { getMetadata, recognized } = api, metadata = getMetadata();
|
|
1303
|
+
if (metadata.duration >= minDuration && metadata.distance.straight.fromStart >= minDistance) {
|
|
1304
|
+
recognized();
|
|
1305
|
+
}
|
|
1306
|
+
};
|
|
1307
|
+
const mouseleave = (event, api) => {
|
|
1308
|
+
const { denied } = api;
|
|
1309
|
+
if (mouseStatus === "down") {
|
|
1310
|
+
denied();
|
|
1311
|
+
cleanup(event);
|
|
1312
|
+
mouseStatus = "leave";
|
|
1313
|
+
}
|
|
1314
|
+
onLeave?.(toHookApi(api));
|
|
1315
|
+
};
|
|
1316
|
+
const mouseup = (event, api) => {
|
|
1317
|
+
const { denied } = api;
|
|
1318
|
+
if (mouseStatus !== "down")
|
|
1319
|
+
return;
|
|
1320
|
+
denied();
|
|
1321
|
+
cleanup(event);
|
|
1322
|
+
mouseStatus = "up";
|
|
1323
|
+
onUp?.(toHookApi(api));
|
|
1324
|
+
};
|
|
1325
|
+
return {
|
|
1326
|
+
mousedown,
|
|
1327
|
+
mouseleave,
|
|
1328
|
+
mouseup
|
|
1329
|
+
};
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1332
|
+
const defaultOptions$e = {
|
|
1333
|
+
minDuration: 0,
|
|
1334
|
+
minDistance: 0,
|
|
1335
|
+
minVelocity: 0,
|
|
1336
|
+
getMousemoveTarget: (event) => event.target
|
|
1337
|
+
};
|
|
1338
|
+
function createMouserelease(options = {}) {
|
|
1339
|
+
const {
|
|
1340
|
+
minDuration,
|
|
1341
|
+
minDistance,
|
|
1342
|
+
minVelocity,
|
|
1343
|
+
getMousemoveTarget,
|
|
1344
|
+
onDown,
|
|
1345
|
+
onLeave,
|
|
1346
|
+
onMove,
|
|
1347
|
+
onUp
|
|
1348
|
+
} = { ...defaultOptions$e, ...options }, cleanup = (event) => {
|
|
1349
|
+
window.cancelAnimationFrame(request);
|
|
1350
|
+
getMousemoveTarget(event).removeEventListener("mousemove", mousemoveEffect);
|
|
1351
|
+
};
|
|
1352
|
+
let request;
|
|
1353
|
+
let mousemoveEffect;
|
|
1354
|
+
let mouseStatus;
|
|
1355
|
+
const mousedown = (event, api) => {
|
|
1356
|
+
mouseStatus = "down";
|
|
1357
|
+
mousemoveEffect = (event2) => mousemove(event2, api);
|
|
1358
|
+
storePointerStartMetadata(event, api);
|
|
1359
|
+
storePointerMoveMetadata(event, api);
|
|
1360
|
+
storePointerTimeMetadata(
|
|
1361
|
+
event,
|
|
1362
|
+
api,
|
|
1363
|
+
() => mouseStatus === "down",
|
|
1364
|
+
(newRequest) => request = newRequest
|
|
1365
|
+
);
|
|
1366
|
+
getMousemoveTarget(event).addEventListener("mousemove", mousemoveEffect);
|
|
1367
|
+
onDown?.(toHookApi(api));
|
|
1368
|
+
};
|
|
1369
|
+
const mousemove = (event, api) => {
|
|
1370
|
+
storePointerMoveMetadata(event, api);
|
|
1371
|
+
onMove?.(toHookApi(api));
|
|
1372
|
+
};
|
|
1373
|
+
const mouseleave = (event, api) => {
|
|
1374
|
+
const { denied } = api;
|
|
1375
|
+
if (mouseStatus === "down") {
|
|
1376
|
+
denied();
|
|
1377
|
+
cleanup(event);
|
|
1378
|
+
mouseStatus = "leave";
|
|
1379
|
+
}
|
|
1380
|
+
onLeave?.(toHookApi(api));
|
|
1381
|
+
};
|
|
1382
|
+
const mouseup = (event, api) => {
|
|
1383
|
+
if (mouseStatus !== "down")
|
|
1384
|
+
return;
|
|
1385
|
+
storePointerMoveMetadata(event, api);
|
|
1386
|
+
cleanup(event);
|
|
1387
|
+
mouseStatus = "up";
|
|
1388
|
+
recognize(event, api);
|
|
1389
|
+
onUp?.(toHookApi(api));
|
|
1390
|
+
};
|
|
1391
|
+
const recognize = (event, api) => {
|
|
1392
|
+
const { getMetadata, recognized, denied } = api, metadata = getMetadata();
|
|
1393
|
+
if (metadata.duration >= minDuration && metadata.distance.straight.fromStart >= minDistance && metadata.velocity >= minVelocity) {
|
|
1394
|
+
recognized();
|
|
1395
|
+
} else {
|
|
1396
|
+
denied();
|
|
1397
|
+
}
|
|
1398
|
+
};
|
|
1399
|
+
return {
|
|
1400
|
+
mousedown,
|
|
1401
|
+
mouseleave,
|
|
1402
|
+
mouseup
|
|
1403
|
+
};
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1406
|
+
const defaultOptions$d = {
|
|
1407
|
+
minDuration: 0,
|
|
1408
|
+
minDistance: 0
|
|
1409
|
+
};
|
|
1410
|
+
function createTouchpress(options = {}) {
|
|
1411
|
+
const {
|
|
1412
|
+
minDuration,
|
|
1413
|
+
minDistance,
|
|
1414
|
+
onStart,
|
|
1415
|
+
onCancel,
|
|
1416
|
+
onMove,
|
|
1417
|
+
onEnd
|
|
1418
|
+
} = { ...defaultOptions$d, ...options }, cleanup = () => {
|
|
1419
|
+
window.cancelAnimationFrame(request);
|
|
1420
|
+
};
|
|
1421
|
+
let request;
|
|
1422
|
+
let totalTouches = 0;
|
|
1423
|
+
const touchstart = (event, api) => {
|
|
1424
|
+
const { denied } = api;
|
|
1425
|
+
totalTouches++;
|
|
1426
|
+
if (totalTouches > 1) {
|
|
1427
|
+
cleanup();
|
|
1428
|
+
denied();
|
|
1429
|
+
onStart?.(toHookApi(api));
|
|
1430
|
+
return;
|
|
1431
|
+
}
|
|
1432
|
+
storePointerStartMetadata(event, api);
|
|
1433
|
+
storePointerMoveMetadata(event, api);
|
|
1434
|
+
storePointerTimeMetadata(
|
|
1435
|
+
event,
|
|
1436
|
+
api,
|
|
1437
|
+
() => totalTouches === 1,
|
|
1438
|
+
(newRequest) => request = newRequest,
|
|
1439
|
+
recognize
|
|
1440
|
+
);
|
|
1441
|
+
onStart?.(toHookApi(api));
|
|
1442
|
+
};
|
|
1443
|
+
const touchmove = (event, api) => {
|
|
1444
|
+
const { getStatus } = api;
|
|
1445
|
+
if (getStatus() !== "denied") {
|
|
1446
|
+
storePointerMoveMetadata(event, api);
|
|
1447
|
+
recognize(event, api);
|
|
1448
|
+
}
|
|
1449
|
+
onMove?.(toHookApi(api));
|
|
1450
|
+
};
|
|
1451
|
+
const recognize = (event, api) => {
|
|
1452
|
+
const { getMetadata, recognized } = api, metadata = getMetadata();
|
|
1453
|
+
if (metadata.duration >= minDuration && metadata.distance.straight.fromStart >= minDistance) {
|
|
1454
|
+
recognized();
|
|
1455
|
+
}
|
|
1456
|
+
};
|
|
1457
|
+
const touchcancel = (event, api) => {
|
|
1458
|
+
const { denied } = api;
|
|
1459
|
+
cleanup();
|
|
1460
|
+
denied();
|
|
1461
|
+
totalTouches--;
|
|
1462
|
+
onCancel?.(toHookApi(api));
|
|
1463
|
+
};
|
|
1464
|
+
const touchend = (event, api) => {
|
|
1465
|
+
const { denied } = api;
|
|
1466
|
+
cleanup();
|
|
1467
|
+
denied();
|
|
1468
|
+
totalTouches--;
|
|
1469
|
+
onEnd?.(toHookApi(api));
|
|
1470
|
+
};
|
|
1471
|
+
return {
|
|
1472
|
+
touchstart,
|
|
1473
|
+
touchmove,
|
|
1474
|
+
touchcancel,
|
|
1475
|
+
touchend
|
|
1476
|
+
};
|
|
1477
|
+
}
|
|
1478
|
+
|
|
1479
|
+
const defaultOptions$c = {
|
|
1480
|
+
minDuration: 0,
|
|
1481
|
+
minDistance: 0,
|
|
1482
|
+
minVelocity: 0
|
|
1483
|
+
};
|
|
1484
|
+
function createTouchrelease(options = {}) {
|
|
1485
|
+
const {
|
|
1486
|
+
minDuration,
|
|
1487
|
+
minDistance,
|
|
1488
|
+
minVelocity,
|
|
1489
|
+
onStart,
|
|
1490
|
+
onCancel,
|
|
1491
|
+
onMove,
|
|
1492
|
+
onEnd
|
|
1493
|
+
} = { ...defaultOptions$c, ...options }, cleanup = () => {
|
|
1494
|
+
window.cancelAnimationFrame(request);
|
|
1495
|
+
};
|
|
1496
|
+
let request;
|
|
1497
|
+
let totalTouches = 0;
|
|
1498
|
+
const touchstart = (event, api) => {
|
|
1499
|
+
const { denied } = api;
|
|
1500
|
+
totalTouches++;
|
|
1501
|
+
if (totalTouches > 1) {
|
|
1502
|
+
cleanup();
|
|
1503
|
+
denied();
|
|
1504
|
+
onStart?.(toHookApi(api));
|
|
1505
|
+
return;
|
|
1506
|
+
}
|
|
1507
|
+
storePointerStartMetadata(event, api);
|
|
1508
|
+
storePointerMoveMetadata(event, api);
|
|
1509
|
+
storePointerTimeMetadata(
|
|
1510
|
+
event,
|
|
1511
|
+
api,
|
|
1512
|
+
() => totalTouches === 1,
|
|
1513
|
+
(newRequest) => request = newRequest
|
|
1514
|
+
);
|
|
1515
|
+
onStart?.(toHookApi(api));
|
|
1516
|
+
};
|
|
1517
|
+
const touchmove = (event, api) => {
|
|
1518
|
+
const { getStatus } = api;
|
|
1519
|
+
if (getStatus() !== "denied")
|
|
1520
|
+
storePointerMoveMetadata(event, api);
|
|
1521
|
+
onMove?.(toHookApi(api));
|
|
1522
|
+
};
|
|
1523
|
+
const touchcancel = (event, api) => {
|
|
1524
|
+
const { denied } = api;
|
|
1525
|
+
cleanup();
|
|
1526
|
+
denied();
|
|
1527
|
+
totalTouches--;
|
|
1528
|
+
onCancel?.(toHookApi(api));
|
|
1529
|
+
};
|
|
1530
|
+
const touchend = (event, api) => {
|
|
1531
|
+
const { denied } = api;
|
|
1532
|
+
if (totalTouches !== 1) {
|
|
1533
|
+
cleanup();
|
|
1534
|
+
denied();
|
|
1535
|
+
onEnd?.(toHookApi(api));
|
|
1536
|
+
return;
|
|
1537
|
+
}
|
|
1538
|
+
storePointerMoveMetadata(event, api);
|
|
1539
|
+
cleanup();
|
|
1540
|
+
totalTouches--;
|
|
1541
|
+
recognize(event, api);
|
|
1542
|
+
onEnd?.(toHookApi(api));
|
|
1543
|
+
};
|
|
1544
|
+
const recognize = (event, api) => {
|
|
1545
|
+
const { getMetadata, recognized, denied } = api, metadata = getMetadata();
|
|
1546
|
+
if (metadata.duration >= minDuration && metadata.distance.straight.fromStart >= minDistance && metadata.velocity >= minVelocity) {
|
|
1547
|
+
recognized();
|
|
1548
|
+
} else {
|
|
1549
|
+
denied();
|
|
1550
|
+
}
|
|
1551
|
+
};
|
|
1552
|
+
return {
|
|
1553
|
+
touchstart,
|
|
1554
|
+
touchmove,
|
|
1555
|
+
touchcancel,
|
|
1556
|
+
touchend
|
|
1557
|
+
};
|
|
1558
|
+
}
|
|
1559
|
+
|
|
1560
|
+
const defaultOptions$b = {
|
|
1561
|
+
initial: []
|
|
1562
|
+
};
|
|
1563
|
+
function createKeyStatuses(options = {}) {
|
|
1564
|
+
return createAssociativeArray({
|
|
1565
|
+
...defaultOptions$b,
|
|
1566
|
+
...options,
|
|
1567
|
+
createPredicateKey: (query) => (key) => {
|
|
1568
|
+
for (const prop in query) {
|
|
1569
|
+
if (query[prop] !== key[prop]) {
|
|
1570
|
+
return false;
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
return true;
|
|
1574
|
+
}
|
|
1575
|
+
});
|
|
1576
|
+
}
|
|
1577
|
+
function predicateDown(status) {
|
|
1578
|
+
return status === "down";
|
|
1579
|
+
}
|
|
1580
|
+
function predicateSomeKeyDown(statuses) {
|
|
1581
|
+
return includes("down")(statuses.toValues());
|
|
1582
|
+
}
|
|
1583
|
+
|
|
1584
|
+
function fromComboToAliases(combo) {
|
|
1585
|
+
const delimiter = "+";
|
|
1586
|
+
return pipe(
|
|
1587
|
+
unique(),
|
|
1588
|
+
map((name) => name === "" ? delimiter : name.toLowerCase()),
|
|
1589
|
+
toArray()
|
|
1590
|
+
)(combo.split(delimiter));
|
|
1591
|
+
}
|
|
1592
|
+
|
|
1593
|
+
function fromAliasToKeyStatusKey(alias) {
|
|
1594
|
+
if (alias in keysByAlias) {
|
|
1595
|
+
return { key: keysByAlias[alias] };
|
|
1596
|
+
}
|
|
1597
|
+
return {
|
|
1598
|
+
code: (() => {
|
|
1599
|
+
if (alias in codesByAlias)
|
|
1600
|
+
return codesByAlias[alias];
|
|
1601
|
+
if (letterRE.test(alias))
|
|
1602
|
+
return `Key${alias.toUpperCase()}`;
|
|
1603
|
+
if (digitRE.test(alias))
|
|
1604
|
+
return `Digit${alias}`;
|
|
1605
|
+
if (functionRE.test(alias))
|
|
1606
|
+
return alias.toUpperCase();
|
|
1607
|
+
return "unsupported";
|
|
1608
|
+
})()
|
|
1609
|
+
};
|
|
1610
|
+
}
|
|
1611
|
+
const digitRE = /^[0-9]$/;
|
|
1612
|
+
const letterRE = /^[a-zA-Z]$/;
|
|
1613
|
+
const functionRE = /^[fF][0-9]{1,2}$/;
|
|
1614
|
+
const codesByAlias = {
|
|
1615
|
+
"`": "Backquote",
|
|
1616
|
+
"~": "Backquote",
|
|
1617
|
+
"-": "Minus",
|
|
1618
|
+
_: "Minus",
|
|
1619
|
+
"=": "Equal",
|
|
1620
|
+
"+": "Equal",
|
|
1621
|
+
"[": "BracketLeft",
|
|
1622
|
+
"{": "BracketLeft",
|
|
1623
|
+
"]": "BracketRight",
|
|
1624
|
+
"}": "BracketRight",
|
|
1625
|
+
"\\": "Backslash",
|
|
1626
|
+
"|": "Backslash",
|
|
1627
|
+
";": "Semicolon",
|
|
1628
|
+
":": "Semicolon",
|
|
1629
|
+
"'": "Quote",
|
|
1630
|
+
'"': "Quote",
|
|
1631
|
+
",": "Comma",
|
|
1632
|
+
"<": "Comma",
|
|
1633
|
+
".": "Period",
|
|
1634
|
+
">": "Period",
|
|
1635
|
+
"/": "Slash",
|
|
1636
|
+
"?": "Slash",
|
|
1637
|
+
"!": "Digit1",
|
|
1638
|
+
"@": "Digit2",
|
|
1639
|
+
"#": "Digit3",
|
|
1640
|
+
$: "Digit4",
|
|
1641
|
+
"%": "Digit5",
|
|
1642
|
+
"^": "Digit6",
|
|
1643
|
+
"&": "Digit7",
|
|
1644
|
+
"*": "Digit8",
|
|
1645
|
+
"(": "Digit9",
|
|
1646
|
+
")": "Digit0",
|
|
1647
|
+
up: "ArrowUp",
|
|
1648
|
+
down: "ArrowDown",
|
|
1649
|
+
left: "ArrowLeft",
|
|
1650
|
+
right: "ArrowRight",
|
|
1651
|
+
enter: "Enter",
|
|
1652
|
+
space: "Space",
|
|
1653
|
+
tab: "Tab",
|
|
1654
|
+
esc: "Escape",
|
|
1655
|
+
backspace: "Backspace",
|
|
1656
|
+
delete: "Delete",
|
|
1657
|
+
home: "Home",
|
|
1658
|
+
end: "End",
|
|
1659
|
+
pagedown: "PageDown",
|
|
1660
|
+
pageup: "PageUp",
|
|
1661
|
+
capslock: "CapsLock",
|
|
1662
|
+
camera: "Camera"
|
|
1663
|
+
};
|
|
1664
|
+
const keysByAlias = {
|
|
1665
|
+
alt: "Alt",
|
|
1666
|
+
opt: "Alt",
|
|
1667
|
+
option: "Alt",
|
|
1668
|
+
ctrl: "Control",
|
|
1669
|
+
control: "Control",
|
|
1670
|
+
meta: "Meta",
|
|
1671
|
+
cmd: "Meta",
|
|
1672
|
+
command: "Meta",
|
|
1673
|
+
shift: "Shift"
|
|
1674
|
+
};
|
|
1675
|
+
|
|
1676
|
+
const defaultOptions$a = {
|
|
1677
|
+
toKey: (alias) => fromAliasToKeyStatusKey(alias)
|
|
1678
|
+
};
|
|
1679
|
+
const createPredicateKeycomboDown = (keycombo, options = {}) => {
|
|
1680
|
+
const { toKey } = { ...defaultOptions$a, ...options }, keys = pipe(
|
|
1681
|
+
fromComboToAliases,
|
|
1682
|
+
map(toKey)
|
|
1683
|
+
)(keycombo);
|
|
1684
|
+
return (statuses) => {
|
|
1685
|
+
const { toValue } = statuses;
|
|
1686
|
+
return every(pipe(
|
|
1687
|
+
toValue,
|
|
1688
|
+
predicateDown
|
|
1689
|
+
))(keys);
|
|
1690
|
+
};
|
|
1691
|
+
};
|
|
1692
|
+
|
|
1693
|
+
function fromEventToAliases(event) {
|
|
1694
|
+
if (event.shiftKey && event.code in aliasesByShiftCode) {
|
|
1695
|
+
return [aliasesByShiftCode[event.code]];
|
|
1696
|
+
}
|
|
1697
|
+
if (event.key in aliasListsByModifier) {
|
|
1698
|
+
return aliasListsByModifier[event.key];
|
|
1699
|
+
}
|
|
1700
|
+
return event.code in aliasesByCode ? [aliasesByCode[event.code]] : [event.code.match(aliasCaptureRE)?.[1].toLowerCase() || "unsupported"];
|
|
1701
|
+
}
|
|
1702
|
+
const aliasCaptureRE = /^(?:Digit|Key)?(F[0-9]{1,2}|[0-9]|[A-Z])$/;
|
|
1703
|
+
const aliasesByCode = {
|
|
1704
|
+
Backquote: "`",
|
|
1705
|
+
Minus: "-",
|
|
1706
|
+
Equal: "=",
|
|
1707
|
+
BracketLeft: "[",
|
|
1708
|
+
BracketRight: "]",
|
|
1709
|
+
Backslash: "\\",
|
|
1710
|
+
Semicolon: ";",
|
|
1711
|
+
Quote: "'",
|
|
1712
|
+
Comma: ",",
|
|
1713
|
+
Period: ".",
|
|
1714
|
+
Slash: "/",
|
|
1715
|
+
ArrowUp: "up",
|
|
1716
|
+
ArrowDown: "down",
|
|
1717
|
+
ArrowLeft: "left",
|
|
1718
|
+
ArrowRight: "right",
|
|
1719
|
+
Enter: "enter",
|
|
1720
|
+
Space: "space",
|
|
1721
|
+
Tab: "tab",
|
|
1722
|
+
Escape: "esc",
|
|
1723
|
+
Backspace: "backspace",
|
|
1724
|
+
Delete: "delete",
|
|
1725
|
+
Home: "home",
|
|
1726
|
+
End: "end",
|
|
1727
|
+
PageDown: "pagedown",
|
|
1728
|
+
PageUp: "pageup",
|
|
1729
|
+
CapsLock: "capslock",
|
|
1730
|
+
Camera: "camera"
|
|
1731
|
+
};
|
|
1732
|
+
const aliasesByShiftCode = {
|
|
1733
|
+
Backquote: "~",
|
|
1734
|
+
Minus: "_",
|
|
1735
|
+
Equal: "+",
|
|
1736
|
+
BracketLeft: "{",
|
|
1737
|
+
BracketRight: "}",
|
|
1738
|
+
Backslash: "|",
|
|
1739
|
+
Semicolon: ":",
|
|
1740
|
+
Quote: '"',
|
|
1741
|
+
Comma: "<",
|
|
1742
|
+
Period: ">",
|
|
1743
|
+
Slash: "?",
|
|
1744
|
+
Digit1: "!",
|
|
1745
|
+
Digit2: "@",
|
|
1746
|
+
Digit3: "#",
|
|
1747
|
+
Digit4: "$",
|
|
1748
|
+
Digit5: "%",
|
|
1749
|
+
Digit6: "^",
|
|
1750
|
+
Digit7: "&",
|
|
1751
|
+
Digit8: "*",
|
|
1752
|
+
Digit9: "(",
|
|
1753
|
+
Digit0: ")"
|
|
1754
|
+
};
|
|
1755
|
+
const aliasListsByModifier = {
|
|
1756
|
+
Alt: ["alt", "option", "opt"],
|
|
1757
|
+
Control: ["control", "ctrl"],
|
|
1758
|
+
Meta: ["meta", "command", "cmd"],
|
|
1759
|
+
Shift: ["shift"]
|
|
1760
|
+
};
|
|
1761
|
+
|
|
1762
|
+
const defaultOptions$9 = {
|
|
1763
|
+
toKey: (alias) => fromAliasToKeyStatusKey(alias),
|
|
1764
|
+
toAliases: (event) => fromEventToAliases(event)
|
|
1765
|
+
};
|
|
1766
|
+
const createPredicateKeycomboMatch = (keycombo, options = {}) => {
|
|
1767
|
+
const { toKey, toAliases } = { ...defaultOptions$9, ...options }, aliases = fromComboToAliases(keycombo), keys = map(toKey)(aliases);
|
|
1768
|
+
return (statuses) => {
|
|
1769
|
+
const { toValue } = statuses;
|
|
1770
|
+
return every(pipe(
|
|
1771
|
+
toValue,
|
|
1772
|
+
predicateDown
|
|
1773
|
+
))(keys) && every(
|
|
1774
|
+
([key, value]) => value === "up" || some(
|
|
1775
|
+
(alias) => includes(alias)(aliases)
|
|
1776
|
+
)(toAliases(key))
|
|
1777
|
+
)(statuses.toEntries());
|
|
1778
|
+
};
|
|
1779
|
+
};
|
|
1780
|
+
|
|
1781
|
+
function createKeyState({
|
|
1782
|
+
keycomboOrKeycombos,
|
|
1783
|
+
unsupportedAliases,
|
|
1784
|
+
toKey,
|
|
1785
|
+
toAliases,
|
|
1786
|
+
getRequest
|
|
1787
|
+
}) {
|
|
1788
|
+
const narrowedKeycombos = createFilter(
|
|
1789
|
+
(keycombo) => !some(
|
|
1790
|
+
(alias) => includes(alias)(unsupportedAliases)
|
|
1791
|
+
)(fromComboToAliases(keycombo))
|
|
1792
|
+
)(Array.isArray(keycomboOrKeycombos) ? keycomboOrKeycombos : [keycomboOrKeycombos]), createPredicateKeycomboDownOptions = { toKey }, downPredicatesByKeycombo = (() => {
|
|
1793
|
+
const predicates = [];
|
|
1794
|
+
for (const keycombo of narrowedKeycombos) {
|
|
1795
|
+
predicates.push([
|
|
1796
|
+
keycombo,
|
|
1797
|
+
createPredicateKeycomboDown(
|
|
1798
|
+
keycombo,
|
|
1799
|
+
createPredicateKeycomboDownOptions
|
|
1800
|
+
)
|
|
1801
|
+
]);
|
|
165
1802
|
}
|
|
166
|
-
return
|
|
1803
|
+
return predicates;
|
|
1804
|
+
})(), createPredicateKeycomboMatchOptions = { ...createPredicateKeycomboDownOptions, toAliases }, matchPredicatesByKeycombo = (() => {
|
|
1805
|
+
const predicates = {};
|
|
1806
|
+
for (const keycombo of narrowedKeycombos) {
|
|
1807
|
+
predicates[keycombo] = createPredicateKeycomboMatch(
|
|
1808
|
+
keycombo,
|
|
1809
|
+
createPredicateKeycomboMatchOptions
|
|
1810
|
+
);
|
|
1811
|
+
}
|
|
1812
|
+
return predicates;
|
|
1813
|
+
})(), validAliases = pipe(
|
|
1814
|
+
flatMap(fromComboToAliases),
|
|
1815
|
+
unique(),
|
|
1816
|
+
toArray()
|
|
1817
|
+
)(narrowedKeycombos), getDownCombos = () => pipe(
|
|
1818
|
+
filter(([, predicate]) => predicate(statuses)),
|
|
1819
|
+
map(([keycombo]) => [keycombo, fromComboToAliases(keycombo)]),
|
|
1820
|
+
sort(([, aliasesA], [, aliasesB]) => aliasesB.length - aliasesA.length),
|
|
1821
|
+
map(([keycombo]) => keycombo),
|
|
1822
|
+
toArray()
|
|
1823
|
+
)(downPredicatesByKeycombo), predicateValid = (event) => {
|
|
1824
|
+
const aliases = toAliases(event);
|
|
1825
|
+
return some(
|
|
1826
|
+
(validAlias) => includes(validAlias)(aliases)
|
|
1827
|
+
)(validAliases);
|
|
1828
|
+
}, cleanup = () => {
|
|
1829
|
+
window.cancelAnimationFrame(getRequest());
|
|
1830
|
+
}, statuses = createKeyStatuses();
|
|
1831
|
+
return {
|
|
1832
|
+
narrowedKeycombos,
|
|
1833
|
+
createPredicateKeycomboDownOptions,
|
|
1834
|
+
downPredicatesByKeycombo,
|
|
1835
|
+
createPredicateKeycomboMatchOptions,
|
|
1836
|
+
matchPredicatesByKeycombo,
|
|
1837
|
+
validAliases,
|
|
1838
|
+
getDownCombos,
|
|
1839
|
+
predicateValid,
|
|
1840
|
+
cleanup,
|
|
1841
|
+
statuses
|
|
167
1842
|
};
|
|
168
1843
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
(sliced) => compare ? sliced.sort(compare) : sliced.sort()
|
|
174
|
-
);
|
|
1844
|
+
|
|
1845
|
+
function toLength() {
|
|
1846
|
+
return function toLengthFn(data) {
|
|
1847
|
+
return [...data].length;
|
|
175
1848
|
};
|
|
176
1849
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
1850
|
+
|
|
1851
|
+
const fromComboToAliasesLength = pipe(
|
|
1852
|
+
fromComboToAliases,
|
|
1853
|
+
toLength()
|
|
1854
|
+
);
|
|
1855
|
+
|
|
1856
|
+
function fromEventToKeyStatusKey({ key, code }) {
|
|
1857
|
+
return includes(key)(modifiers) ? { key } : { code };
|
|
181
1858
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
1859
|
+
const modifiers = ["Alt", "Control", "Meta", "Shift"];
|
|
1860
|
+
|
|
1861
|
+
function toDirection(angle, unit = "degrees") {
|
|
1862
|
+
return Object.keys(directions).find((direction) => directions[direction][unit](angle));
|
|
186
1863
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
1864
|
+
const directions = {
|
|
1865
|
+
up: {
|
|
1866
|
+
degrees: (degrees) => degrees >= 67.5 && degrees <= 112.5,
|
|
1867
|
+
radians: (radians) => radians >= 0.375 * Math.PI && radians <= 0.625 * Math.PI
|
|
1868
|
+
},
|
|
1869
|
+
upRight: {
|
|
1870
|
+
degrees: (degrees) => degrees >= 22.5 && degrees < 67.5,
|
|
1871
|
+
radians: (radians) => radians >= 0.125 * Math.PI && radians < 0.375 * Math.PI
|
|
1872
|
+
},
|
|
1873
|
+
right: {
|
|
1874
|
+
degrees: (degrees) => degrees > 337.5 && degrees <= 360 || degrees < 22.5 && degrees >= 0,
|
|
1875
|
+
radians: (radians) => radians > 1.875 * Math.PI && radians <= 2 * Math.PI || radians < 0.125 * Math.PI && radians >= 0
|
|
1876
|
+
},
|
|
1877
|
+
downRight: {
|
|
1878
|
+
degrees: (degrees) => degrees > 292.5 && degrees <= 337.5,
|
|
1879
|
+
radians: (radians) => radians > 1.625 * Math.PI && radians <= 1.875 * Math.PI
|
|
1880
|
+
},
|
|
1881
|
+
down: {
|
|
1882
|
+
degrees: (degrees) => degrees >= 247.5 && degrees <= 292.5,
|
|
1883
|
+
radians: (radians) => radians >= 1.375 * Math.PI && radians <= 1.625 * Math.PI
|
|
1884
|
+
},
|
|
1885
|
+
downLeft: {
|
|
1886
|
+
degrees: (degrees) => degrees >= 202.5 && degrees < 247.5,
|
|
1887
|
+
radians: (radians) => radians >= 1.125 * Math.PI && radians < 1.375 * Math.PI
|
|
1888
|
+
},
|
|
1889
|
+
left: {
|
|
1890
|
+
degrees: (degrees) => degrees > 157.5 && degrees < 202.5,
|
|
1891
|
+
radians: (radians) => radians > 0.875 * Math.PI && radians < 1.125 * Math.PI
|
|
1892
|
+
},
|
|
1893
|
+
upLeft: {
|
|
1894
|
+
degrees: (degrees) => degrees > 112.5 && degrees <= 157.5,
|
|
1895
|
+
radians: (radians) => radians > 0.625 * Math.PI && radians <= 0.875 * Math.PI
|
|
1896
|
+
}
|
|
1897
|
+
};
|
|
1898
|
+
|
|
1899
|
+
function toHookApi({
|
|
1900
|
+
getSequence,
|
|
1901
|
+
getStatus,
|
|
1902
|
+
getMetadata
|
|
1903
|
+
}) {
|
|
1904
|
+
return {
|
|
1905
|
+
sequence: getSequence(),
|
|
1906
|
+
status: getStatus(),
|
|
1907
|
+
metadata: getMetadata()
|
|
191
1908
|
};
|
|
192
1909
|
}
|
|
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;
|
|
1910
|
+
|
|
1911
|
+
function toMousePoint(event) {
|
|
1912
|
+
return {
|
|
1913
|
+
x: event.clientX,
|
|
1914
|
+
y: event.clientY
|
|
1915
|
+
};
|
|
205
1916
|
}
|
|
206
|
-
function
|
|
207
|
-
return
|
|
208
|
-
|
|
209
|
-
|
|
1917
|
+
function toTouchMovePoint(event) {
|
|
1918
|
+
return {
|
|
1919
|
+
x: event.touches.item(0).clientX,
|
|
1920
|
+
y: event.touches.item(0).clientY
|
|
210
1921
|
};
|
|
211
1922
|
}
|
|
212
|
-
function
|
|
213
|
-
return
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
entries.push([key, object[key]]);
|
|
217
|
-
}
|
|
218
|
-
return entries;
|
|
1923
|
+
function toTouchEndPoint(event) {
|
|
1924
|
+
return {
|
|
1925
|
+
x: event.changedTouches.item(0).clientX,
|
|
1926
|
+
y: event.changedTouches.item(0).clientY
|
|
219
1927
|
};
|
|
220
1928
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
}
|
|
227
|
-
return keys;
|
|
1929
|
+
|
|
1930
|
+
function toPolarCoordinates({ xA, xB, yA, yB }) {
|
|
1931
|
+
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;
|
|
1932
|
+
return {
|
|
1933
|
+
distance,
|
|
1934
|
+
angle: { radians, degrees }
|
|
228
1935
|
};
|
|
229
1936
|
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
1937
|
+
|
|
1938
|
+
const initialMetadata$3 = {
|
|
1939
|
+
times: {
|
|
1940
|
+
start: 0,
|
|
1941
|
+
end: 0
|
|
1942
|
+
},
|
|
1943
|
+
duration: 0
|
|
1944
|
+
};
|
|
1945
|
+
function storeKeyboardTimeMetadata({
|
|
1946
|
+
event,
|
|
1947
|
+
api,
|
|
1948
|
+
getTimeMetadata,
|
|
1949
|
+
getShouldStore,
|
|
1950
|
+
setRequest,
|
|
1951
|
+
recognize
|
|
1952
|
+
}) {
|
|
1953
|
+
if (!getShouldStore())
|
|
1954
|
+
return;
|
|
1955
|
+
const { getStatus, onRecognized } = api, timeMetadata = getTimeMetadata();
|
|
1956
|
+
if (!timeMetadata.times)
|
|
1957
|
+
timeMetadata.times = createClone()(initialMetadata$3.times);
|
|
1958
|
+
timeMetadata.times.start = Math.round(event.timeStamp);
|
|
1959
|
+
timeMetadata.times.end = Math.round(event.timeStamp);
|
|
1960
|
+
const storeDuration = () => {
|
|
1961
|
+
const request = requestAnimationFrame((timestamp) => {
|
|
1962
|
+
if (!getShouldStore())
|
|
1963
|
+
return;
|
|
1964
|
+
timeMetadata.times.end = Math.round(timestamp);
|
|
1965
|
+
timeMetadata.duration = Math.max(0, timeMetadata.times.end - timeMetadata.times.start);
|
|
1966
|
+
if (recognize) {
|
|
1967
|
+
recognize(event, api);
|
|
1968
|
+
if (getStatus() === "recognized")
|
|
1969
|
+
onRecognized(event);
|
|
235
1970
|
}
|
|
236
|
-
|
|
237
|
-
|
|
1971
|
+
storeDuration();
|
|
1972
|
+
});
|
|
1973
|
+
setRequest(request);
|
|
238
1974
|
};
|
|
1975
|
+
storeDuration();
|
|
239
1976
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
1977
|
+
|
|
1978
|
+
const initialMetadata$2 = {
|
|
1979
|
+
points: {
|
|
1980
|
+
start: { x: 0, y: 0 },
|
|
1981
|
+
end: { x: 0, y: 0 }
|
|
1982
|
+
}
|
|
1983
|
+
};
|
|
1984
|
+
function storePointerStartMetadata(event, api) {
|
|
1985
|
+
const { getMetadata } = api, metadata = getMetadata();
|
|
1986
|
+
const point = event instanceof MouseEvent ? toMousePoint(event) : toTouchMovePoint(event);
|
|
1987
|
+
if (!metadata.points)
|
|
1988
|
+
metadata.points = createClone()(initialMetadata$2.points);
|
|
1989
|
+
metadata.points.start = point;
|
|
1990
|
+
metadata.points.end = point;
|
|
1991
|
+
}
|
|
1992
|
+
|
|
1993
|
+
const initialMetadata$1 = {
|
|
1994
|
+
distance: {
|
|
1995
|
+
straight: {
|
|
1996
|
+
fromStart: 0,
|
|
1997
|
+
fromPrevious: 0
|
|
1998
|
+
},
|
|
1999
|
+
horizontal: {
|
|
2000
|
+
fromStart: 0,
|
|
2001
|
+
fromPrevious: 0
|
|
2002
|
+
},
|
|
2003
|
+
vertical: {
|
|
2004
|
+
fromStart: 0,
|
|
2005
|
+
fromPrevious: 0
|
|
2006
|
+
}
|
|
2007
|
+
},
|
|
2008
|
+
angle: {
|
|
2009
|
+
fromPrevious: { radians: 0, degrees: 0 },
|
|
2010
|
+
fromStart: { radians: 0, degrees: 0 }
|
|
2011
|
+
},
|
|
2012
|
+
direction: {
|
|
2013
|
+
fromPrevious: "up",
|
|
2014
|
+
fromStart: "up"
|
|
2015
|
+
}
|
|
2016
|
+
};
|
|
2017
|
+
function storePointerMoveMetadata(event, api) {
|
|
2018
|
+
const { getMetadata } = api, metadata = getMetadata();
|
|
2019
|
+
if (!metadata.distance) {
|
|
2020
|
+
metadata.distance = createClone()(initialMetadata$1.distance);
|
|
2021
|
+
metadata.angle = createClone()(initialMetadata$1.angle);
|
|
2022
|
+
metadata.direction = createClone()(initialMetadata$1.direction);
|
|
2023
|
+
}
|
|
2024
|
+
const { x: previousX, y: previousY } = metadata.points.end, { x: startX, y: startY } = metadata.points.start, { x: newX, y: newY } = (() => {
|
|
2025
|
+
if (event instanceof MouseEvent) {
|
|
2026
|
+
return toMousePoint(event);
|
|
2027
|
+
}
|
|
2028
|
+
if (event instanceof TouchEvent) {
|
|
2029
|
+
if (event.type === "touchmove") {
|
|
2030
|
+
return toTouchMovePoint(event);
|
|
245
2031
|
}
|
|
2032
|
+
return toTouchEndPoint(event);
|
|
246
2033
|
}
|
|
247
|
-
|
|
2034
|
+
})(), { distance: distanceFromPrevious, angle: angleFromPrevious } = toPolarCoordinates({
|
|
2035
|
+
xA: previousX,
|
|
2036
|
+
xB: newX,
|
|
2037
|
+
yA: previousY,
|
|
2038
|
+
yB: newY
|
|
2039
|
+
}), { distance: distanceFromStart, angle: angleFromStart } = toPolarCoordinates({
|
|
2040
|
+
xA: startX,
|
|
2041
|
+
xB: newX,
|
|
2042
|
+
yA: startY,
|
|
2043
|
+
yB: newY
|
|
2044
|
+
});
|
|
2045
|
+
metadata.distance.straight.fromPrevious = distanceFromPrevious;
|
|
2046
|
+
metadata.distance.horizontal.fromPrevious = newX - previousX;
|
|
2047
|
+
metadata.distance.vertical.fromPrevious = newY - previousY;
|
|
2048
|
+
metadata.angle.fromPrevious = angleFromPrevious;
|
|
2049
|
+
metadata.direction.fromPrevious = toDirection(angleFromPrevious.degrees);
|
|
2050
|
+
metadata.distance.straight.fromStart = distanceFromStart;
|
|
2051
|
+
metadata.distance.horizontal.fromStart = newX - startX;
|
|
2052
|
+
metadata.distance.vertical.fromStart = newY - startY;
|
|
2053
|
+
metadata.angle.fromStart = angleFromStart;
|
|
2054
|
+
metadata.direction.fromStart = toDirection(angleFromStart.degrees);
|
|
2055
|
+
metadata.points.end = { x: newX, y: newY };
|
|
2056
|
+
}
|
|
2057
|
+
|
|
2058
|
+
const initialMetadata = {
|
|
2059
|
+
times: {
|
|
2060
|
+
start: 0,
|
|
2061
|
+
end: 0
|
|
2062
|
+
},
|
|
2063
|
+
duration: 0,
|
|
2064
|
+
velocity: 0
|
|
2065
|
+
};
|
|
2066
|
+
function storePointerTimeMetadata(event, api, getShouldStore, setRequest, recognize) {
|
|
2067
|
+
const { getMetadata, getStatus, onRecognized } = api, metadata = getMetadata();
|
|
2068
|
+
if (!metadata.times) {
|
|
2069
|
+
metadata.times = createClone()(initialMetadata.times);
|
|
2070
|
+
}
|
|
2071
|
+
metadata.times.start = Math.round(event.timeStamp);
|
|
2072
|
+
metadata.times.end = Math.round(event.timeStamp);
|
|
2073
|
+
let previousTime = metadata.times.start;
|
|
2074
|
+
const storeDuration = () => {
|
|
2075
|
+
const request = requestAnimationFrame((timestamp) => {
|
|
2076
|
+
if (getShouldStore()) {
|
|
2077
|
+
previousTime = metadata.times.end;
|
|
2078
|
+
metadata.times.end = Math.round(timestamp);
|
|
2079
|
+
metadata.duration = Math.max(0, metadata.times.end - metadata.times.start);
|
|
2080
|
+
const durationFromPrevious = Math.max(0, metadata.times.end - previousTime);
|
|
2081
|
+
metadata.velocity = metadata.distance.straight.fromPrevious / durationFromPrevious;
|
|
2082
|
+
recognize?.(event, api);
|
|
2083
|
+
if (getStatus() === "recognized")
|
|
2084
|
+
onRecognized(event);
|
|
2085
|
+
storeDuration();
|
|
2086
|
+
}
|
|
2087
|
+
});
|
|
2088
|
+
setRequest(request);
|
|
248
2089
|
};
|
|
2090
|
+
storeDuration();
|
|
249
2091
|
}
|
|
250
|
-
|
|
251
|
-
|
|
2092
|
+
|
|
2093
|
+
function defineGraph(nodes, edges) {
|
|
2094
|
+
return { nodes, edges };
|
|
252
2095
|
}
|
|
253
|
-
function
|
|
254
|
-
return
|
|
2096
|
+
function defineGraphNodes(nodes) {
|
|
2097
|
+
return nodes;
|
|
255
2098
|
}
|
|
256
|
-
function
|
|
257
|
-
return
|
|
2099
|
+
function defineGraphEdges(edges) {
|
|
2100
|
+
return edges;
|
|
258
2101
|
}
|
|
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
|
-
};
|
|
2102
|
+
function defineGraphNode(node) {
|
|
2103
|
+
return node;
|
|
280
2104
|
}
|
|
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
|
-
}
|
|
2105
|
+
function defineGraphEdge(from, to, predicateTraversable) {
|
|
2106
|
+
return { from, to, predicateTraversable };
|
|
294
2107
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
return name in keysByName ? keysByName[name] : name;
|
|
2108
|
+
function defineAsyncGraph(nodes, edges) {
|
|
2109
|
+
return { nodes, edges };
|
|
298
2110
|
}
|
|
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
|
-
);
|
|
2111
|
+
function defineAsyncGraphEdges(edges) {
|
|
2112
|
+
return edges;
|
|
353
2113
|
}
|
|
354
|
-
function
|
|
355
|
-
return
|
|
2114
|
+
function defineAsyncGraphEdge(from, to, predicateTraversable) {
|
|
2115
|
+
return { from, to, predicateTraversable };
|
|
356
2116
|
}
|
|
357
|
-
|
|
358
|
-
|
|
2117
|
+
|
|
2118
|
+
function defineAssociativeArrayEntries(entries) {
|
|
2119
|
+
return entries;
|
|
359
2120
|
}
|
|
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
|
-
};
|
|
2121
|
+
|
|
400
2122
|
function createExceptAndOnlyEffect(type, effect, options) {
|
|
401
2123
|
const { except = [], only = [] } = options;
|
|
402
2124
|
if (type === "keydown" || type === "keyup") {
|
|
403
2125
|
return (event) => {
|
|
404
|
-
const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false,
|
|
2126
|
+
const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false, false];
|
|
405
2127
|
if (matchesOnly) {
|
|
406
2128
|
effect(event);
|
|
407
2129
|
return;
|
|
@@ -414,7 +2136,7 @@ function createExceptAndOnlyEffect(type, effect, options) {
|
|
|
414
2136
|
}
|
|
415
2137
|
if (type === "click" || type === "dblclick" || type === "contextmenu" || type.startsWith("mouse")) {
|
|
416
2138
|
return (event) => {
|
|
417
|
-
const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false,
|
|
2139
|
+
const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false, false];
|
|
418
2140
|
if (matchesOnly) {
|
|
419
2141
|
effect(event);
|
|
420
2142
|
return;
|
|
@@ -427,7 +2149,7 @@ function createExceptAndOnlyEffect(type, effect, options) {
|
|
|
427
2149
|
}
|
|
428
2150
|
if (type.startsWith("pointer")) {
|
|
429
2151
|
return (event) => {
|
|
430
|
-
const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false,
|
|
2152
|
+
const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false, false];
|
|
431
2153
|
if (matchesOnly) {
|
|
432
2154
|
effect(event);
|
|
433
2155
|
return;
|
|
@@ -439,7 +2161,7 @@ function createExceptAndOnlyEffect(type, effect, options) {
|
|
|
439
2161
|
};
|
|
440
2162
|
}
|
|
441
2163
|
return (event) => {
|
|
442
|
-
const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false,
|
|
2164
|
+
const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false, false];
|
|
443
2165
|
if (matchesOnly) {
|
|
444
2166
|
effect(event, {});
|
|
445
2167
|
return;
|
|
@@ -450,27 +2172,15 @@ function createExceptAndOnlyEffect(type, effect, options) {
|
|
|
450
2172
|
}
|
|
451
2173
|
};
|
|
452
2174
|
}
|
|
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() {
|
|
2175
|
+
|
|
2176
|
+
function getDomAvailability() {
|
|
468
2177
|
try {
|
|
469
|
-
return !!window;
|
|
2178
|
+
return !!window ? "available" : "unavailable";
|
|
470
2179
|
} catch (error) {
|
|
471
|
-
return
|
|
2180
|
+
return "unavailable";
|
|
472
2181
|
}
|
|
473
2182
|
}
|
|
2183
|
+
|
|
474
2184
|
function predicateArray(value) {
|
|
475
2185
|
return Array.isArray(value);
|
|
476
2186
|
}
|
|
@@ -489,24 +2199,8 @@ function predicateNumber(value) {
|
|
|
489
2199
|
function predicateString(value) {
|
|
490
2200
|
return typeof value === "string";
|
|
491
2201
|
}
|
|
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);
|
|
2202
|
+
function predicateObject(value) {
|
|
2203
|
+
return typeof value === "object";
|
|
510
2204
|
}
|
|
511
2205
|
|
|
512
2206
|
class Recognizeable {
|
|
@@ -519,7 +2213,7 @@ class Recognizeable {
|
|
|
519
2213
|
effects: {}
|
|
520
2214
|
};
|
|
521
2215
|
this.maxSequenceLength = options?.maxSequenceLength || defaultOptions.maxSequenceLength;
|
|
522
|
-
this.effects =
|
|
2216
|
+
this.effects = options?.effects || defaultOptions.effects;
|
|
523
2217
|
this.resetComputedMetadata();
|
|
524
2218
|
this.setSequence(sequence);
|
|
525
2219
|
this.effectApi = {
|
|
@@ -528,8 +2222,6 @@ class Recognizeable {
|
|
|
528
2222
|
setMetadata: (metadata) => this.computedMetadata = metadata,
|
|
529
2223
|
recognized: () => this.recognized(),
|
|
530
2224
|
denied: () => this.denied(),
|
|
531
|
-
recognizedUntilReady: () => this.recognizedUntilReady(),
|
|
532
|
-
deniedUntilReady: () => this.deniedUntilReady(),
|
|
533
2225
|
ready: () => this.ready()
|
|
534
2226
|
};
|
|
535
2227
|
this.ready();
|
|
@@ -544,12 +2236,6 @@ class Recognizeable {
|
|
|
544
2236
|
denied() {
|
|
545
2237
|
this.computedStatus = "denied";
|
|
546
2238
|
}
|
|
547
|
-
recognizedUntilReady() {
|
|
548
|
-
this.computedStatus = "recognized until ready";
|
|
549
|
-
}
|
|
550
|
-
deniedUntilReady() {
|
|
551
|
-
this.computedStatus = "denied until ready";
|
|
552
|
-
}
|
|
553
2239
|
computedStatus;
|
|
554
2240
|
ready() {
|
|
555
2241
|
this.computedStatus = "ready";
|
|
@@ -572,8 +2258,7 @@ class Recognizeable {
|
|
|
572
2258
|
return this;
|
|
573
2259
|
}
|
|
574
2260
|
recognize(sequenceItem, { onRecognized } = {}) {
|
|
575
|
-
|
|
576
|
-
this.recognizing();
|
|
2261
|
+
this.recognizing();
|
|
577
2262
|
const type = this.toType(sequenceItem), excess = predicateNumber(this.maxSequenceLength) ? Math.max(0, this.sequence.length - this.maxSequenceLength) : 0, newSequence = createConcat(
|
|
578
2263
|
createSlice(excess)(this.sequence),
|
|
579
2264
|
[sequenceItem]
|
|
@@ -581,11 +2266,10 @@ class Recognizeable {
|
|
|
581
2266
|
this.effectApi.getSequence = () => newSequence;
|
|
582
2267
|
this.effectApi.onRecognized = onRecognized || (() => {
|
|
583
2268
|
});
|
|
584
|
-
this.effects
|
|
2269
|
+
this.effects[type]?.(sequenceItem, { ...this.effectApi });
|
|
585
2270
|
switch (this.status) {
|
|
586
2271
|
case "ready":
|
|
587
2272
|
case "denied":
|
|
588
|
-
case "denied until ready":
|
|
589
2273
|
this.resetComputedMetadata();
|
|
590
2274
|
this.setSequence([]);
|
|
591
2275
|
break;
|
|
@@ -628,8 +2312,8 @@ class Listenable {
|
|
|
628
2312
|
computedActive;
|
|
629
2313
|
constructor(type, options) {
|
|
630
2314
|
if (type === "recognizeable") {
|
|
631
|
-
this.computedRecognizeable = new Recognizeable([], options?.recognizeable
|
|
632
|
-
this.recognizeableEffectsKeys = Object.keys(options?.recognizeable?.effects
|
|
2315
|
+
this.computedRecognizeable = new Recognizeable([], options?.recognizeable);
|
|
2316
|
+
this.recognizeableEffectsKeys = Object.keys(options?.recognizeable?.effects);
|
|
633
2317
|
}
|
|
634
2318
|
this.computedActive = /* @__PURE__ */ new Set();
|
|
635
2319
|
this.setType(type);
|
|
@@ -729,24 +2413,10 @@ class Listenable {
|
|
|
729
2413
|
this.active.add({ target, id: [this.type, effect] });
|
|
730
2414
|
}
|
|
731
2415
|
recognizeableListen(effect, options) {
|
|
732
|
-
let effectStatus = "ready";
|
|
733
2416
|
const guardedEffect = (sequenceItem) => {
|
|
734
2417
|
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
|
-
}
|
|
2418
|
+
if (this.recognizeable.status === "recognized")
|
|
2419
|
+
effect(sequenceItem);
|
|
750
2420
|
};
|
|
751
2421
|
for (const type of this.recognizeableEffectsKeys) {
|
|
752
2422
|
const listenable = new Listenable(type);
|
|
@@ -767,10 +2437,10 @@ class Listenable {
|
|
|
767
2437
|
}
|
|
768
2438
|
addEventListeners(eventListeners, options) {
|
|
769
2439
|
const { target = document } = options;
|
|
770
|
-
|
|
2440
|
+
for (const eventListener of eventListeners) {
|
|
771
2441
|
target.addEventListener(eventListener[0], eventListener[1], eventListener[2]);
|
|
772
2442
|
this.active.add({ target, id: eventListener });
|
|
773
|
-
}
|
|
2443
|
+
}
|
|
774
2444
|
}
|
|
775
2445
|
listening() {
|
|
776
2446
|
this.computedStatus = "listening";
|
|
@@ -882,109 +2552,22 @@ function toAddEventListenerParams(type, effect, options) {
|
|
|
882
2552
|
const { addEventListener, useCapture } = options, exceptAndOnlyEffect = createExceptAndOnlyEffect(type, effect, options), effectOptions = [addEventListener || useCapture];
|
|
883
2553
|
return { exceptAndOnlyEffect, effectOptions };
|
|
884
2554
|
}
|
|
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
2555
|
const observerAssertionsByType = {
|
|
975
2556
|
intersect: (observer) => observer instanceof IntersectionObserver,
|
|
976
2557
|
mutate: (observer) => observer instanceof MutationObserver,
|
|
977
2558
|
resize: (observer) => observer instanceof ResizeObserver
|
|
978
2559
|
};
|
|
979
2560
|
|
|
980
|
-
const defaultOptions$
|
|
2561
|
+
const defaultOptions$8 = {
|
|
981
2562
|
duration: 0,
|
|
2563
|
+
// delay not supported, because it can be effectd by delayable
|
|
982
2564
|
timing: [
|
|
983
2565
|
0,
|
|
984
2566
|
0,
|
|
985
2567
|
1,
|
|
986
2568
|
1
|
|
987
2569
|
],
|
|
2570
|
+
// linear by default
|
|
988
2571
|
iterations: 1,
|
|
989
2572
|
alternates: false
|
|
990
2573
|
};
|
|
@@ -1005,10 +2588,10 @@ class Animateable {
|
|
|
1005
2588
|
getEaseables;
|
|
1006
2589
|
getReversedEaseables;
|
|
1007
2590
|
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$
|
|
2591
|
+
this.initialDuration = options?.duration || defaultOptions$8.duration;
|
|
2592
|
+
this.controlPoints = fromTimingToControlPoints(options?.timing || defaultOptions$8.timing);
|
|
2593
|
+
this.iterationLimit = options?.iterations || defaultOptions$8.iterations;
|
|
2594
|
+
this.alternates = options?.alternates || defaultOptions$8.alternates;
|
|
1012
2595
|
this.reversedControlPoints = fromControlPointsToReversedControlPoints(this.controlPoints);
|
|
1013
2596
|
this.toAnimationProgress = createToAnimationProgress(this.controlPoints);
|
|
1014
2597
|
this.reversedToAnimationProgress = createToAnimationProgress(this.reversedControlPoints);
|
|
@@ -1084,10 +2667,11 @@ class Animateable {
|
|
|
1084
2667
|
setKeyframes(keyframes) {
|
|
1085
2668
|
this.stop();
|
|
1086
2669
|
this.computedKeyframes = Array.from(keyframes).sort(({ progress: progressA }, { progress: progressB }) => progressA - progressB);
|
|
1087
|
-
this.reversedKeyframes =
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
2670
|
+
this.reversedKeyframes = pipe(
|
|
2671
|
+
reverse$1(),
|
|
2672
|
+
map(({ progress, properties }) => ({ progress: 1 - progress, properties })),
|
|
2673
|
+
toArray()
|
|
2674
|
+
)(this.keyframes);
|
|
1091
2675
|
this.properties = toProperties(this.keyframes);
|
|
1092
2676
|
this.easeables = this.getEaseables({ keyframes: this.keyframes, properties: this.properties });
|
|
1093
2677
|
this.reversedEaseables = this.getReversedEaseables({ keyframes: this.reversedKeyframes, properties: this.properties });
|
|
@@ -1385,7 +2969,7 @@ class Animateable {
|
|
|
1385
2969
|
break;
|
|
1386
2970
|
case "reversing":
|
|
1387
2971
|
this.computedIterations += 1;
|
|
1388
|
-
if (this.
|
|
2972
|
+
if (this.iterationLimit === true || this.iterations < this.iterationLimit) {
|
|
1389
2973
|
this.createAnimate("reverse")(effect, options);
|
|
1390
2974
|
} else {
|
|
1391
2975
|
this.alternateCache.status = "ready";
|
|
@@ -1394,7 +2978,7 @@ class Animateable {
|
|
|
1394
2978
|
}
|
|
1395
2979
|
} else {
|
|
1396
2980
|
this.computedIterations += 1;
|
|
1397
|
-
if (this.
|
|
2981
|
+
if (this.iterationLimit === true || this.iterations < this.iterationLimit) {
|
|
1398
2982
|
this.createAnimate("play")(effect, options);
|
|
1399
2983
|
}
|
|
1400
2984
|
}
|
|
@@ -1410,7 +2994,7 @@ class Animateable {
|
|
|
1410
2994
|
switch (this.alternateCache.status) {
|
|
1411
2995
|
case "playing":
|
|
1412
2996
|
this.computedIterations += 1;
|
|
1413
|
-
if (this.
|
|
2997
|
+
if (this.iterationLimit === true || this.iterations < this.iterationLimit) {
|
|
1414
2998
|
this.createAnimate("play")(effect, options);
|
|
1415
2999
|
} else {
|
|
1416
3000
|
this.alternateCache.status = "ready";
|
|
@@ -1422,7 +3006,7 @@ class Animateable {
|
|
|
1422
3006
|
}
|
|
1423
3007
|
} else {
|
|
1424
3008
|
this.computedIterations += 1;
|
|
1425
|
-
if (this.iterations < this.iterationLimit) {
|
|
3009
|
+
if (this.iterationLimit === true || this.iterations < this.iterationLimit) {
|
|
1426
3010
|
this.createAnimate("reverse")(effect, options);
|
|
1427
3011
|
}
|
|
1428
3012
|
}
|
|
@@ -1631,7 +3215,7 @@ function createGetEaseables(fromKeyframeToControlPoints) {
|
|
|
1631
3215
|
(easeables, property) => {
|
|
1632
3216
|
const propertyKeyframes = createFilter(({ properties: properties2 }) => properties2.hasOwnProperty(property))(keyframes), fromKeyframesToEaseables = createReduce(
|
|
1633
3217
|
(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 ? (
|
|
3218
|
+
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
3219
|
propertyEaseables2.push({
|
|
1636
3220
|
property,
|
|
1637
3221
|
value: { previous, next },
|
|
@@ -1646,7 +3230,7 @@ function createGetEaseables(fromKeyframeToControlPoints) {
|
|
|
1646
3230
|
property,
|
|
1647
3231
|
value: { previous: propertyEaseables[0].value.previous, next: propertyEaseables[0].value.previous },
|
|
1648
3232
|
progress: { start: -1, end: propertyEaseables[0].progress.start },
|
|
1649
|
-
toAnimationProgress: (
|
|
3233
|
+
toAnimationProgress: () => 1,
|
|
1650
3234
|
hasCustomTiming: false
|
|
1651
3235
|
};
|
|
1652
3236
|
return createConcat(
|
|
@@ -1891,14 +3475,14 @@ const easingsNetInOutBack = [
|
|
|
1891
3475
|
1.6
|
|
1892
3476
|
];
|
|
1893
3477
|
|
|
1894
|
-
const defaultOptions$
|
|
3478
|
+
const defaultOptions$7 = {
|
|
1895
3479
|
name: "baleada"
|
|
1896
3480
|
};
|
|
1897
3481
|
class Broadcastable {
|
|
1898
3482
|
name;
|
|
1899
3483
|
constructor(state, options = {}) {
|
|
1900
3484
|
this.setState(state);
|
|
1901
|
-
this.name = options.name ?? defaultOptions$
|
|
3485
|
+
this.name = options.name ?? defaultOptions$7.name;
|
|
1902
3486
|
this.ready();
|
|
1903
3487
|
}
|
|
1904
3488
|
computedStatus;
|
|
@@ -1963,12 +3547,69 @@ function toMessageListenParams(instance, effect) {
|
|
|
1963
3547
|
];
|
|
1964
3548
|
}
|
|
1965
3549
|
|
|
3550
|
+
const defaultOptions$6 = {
|
|
3551
|
+
locales: "en",
|
|
3552
|
+
collator: { sensitivity: "base" }
|
|
3553
|
+
};
|
|
3554
|
+
class Compareable {
|
|
3555
|
+
constructor(string, options = {}) {
|
|
3556
|
+
const locales = options.locales || defaultOptions$6.locales, collatorOptions = { ...defaultOptions$6.collator, ...options.collator }, key = locales + pipe(
|
|
3557
|
+
createEntries(),
|
|
3558
|
+
sort((a, b) => a[0] < b[0] ? -1 : 1),
|
|
3559
|
+
join()
|
|
3560
|
+
)(collatorOptions);
|
|
3561
|
+
this.computedCollator = cache[key] || (cache[key] = new Intl.Collator(locales, collatorOptions));
|
|
3562
|
+
this.setString(string);
|
|
3563
|
+
this.ready();
|
|
3564
|
+
}
|
|
3565
|
+
computedStatus;
|
|
3566
|
+
ready() {
|
|
3567
|
+
this.computedStatus = "ready";
|
|
3568
|
+
}
|
|
3569
|
+
get string() {
|
|
3570
|
+
return this.computedString;
|
|
3571
|
+
}
|
|
3572
|
+
set string(string) {
|
|
3573
|
+
this.setString(string);
|
|
3574
|
+
}
|
|
3575
|
+
get status() {
|
|
3576
|
+
return this.computedStatus;
|
|
3577
|
+
}
|
|
3578
|
+
computedCollator;
|
|
3579
|
+
get collator() {
|
|
3580
|
+
return this.computedCollator;
|
|
3581
|
+
}
|
|
3582
|
+
computedComparison;
|
|
3583
|
+
get comparison() {
|
|
3584
|
+
return this.computedComparison;
|
|
3585
|
+
}
|
|
3586
|
+
computedString;
|
|
3587
|
+
setString(string) {
|
|
3588
|
+
this.computedString = string;
|
|
3589
|
+
return this;
|
|
3590
|
+
}
|
|
3591
|
+
compare(compared) {
|
|
3592
|
+
this.comparing();
|
|
3593
|
+
this.computedComparison = this.computedCollator.compare(this.string, compared);
|
|
3594
|
+
this.compared();
|
|
3595
|
+
return this;
|
|
3596
|
+
}
|
|
3597
|
+
comparing() {
|
|
3598
|
+
this.computedStatus = "comparing";
|
|
3599
|
+
}
|
|
3600
|
+
compared() {
|
|
3601
|
+
this.computedStatus = "compared";
|
|
3602
|
+
}
|
|
3603
|
+
}
|
|
3604
|
+
const cache = {};
|
|
3605
|
+
|
|
1966
3606
|
const defaultOptions$5 = {
|
|
1967
3607
|
segment: {
|
|
1968
3608
|
from: "start",
|
|
1969
3609
|
to: "end"
|
|
1970
3610
|
},
|
|
1971
3611
|
divider: /\s/
|
|
3612
|
+
// 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
3613
|
};
|
|
1973
3614
|
const defaultCompleteOptions = {
|
|
1974
3615
|
select: "completionEnd"
|
|
@@ -2051,6 +3692,7 @@ class Completeable {
|
|
|
2051
3692
|
}
|
|
2052
3693
|
return this;
|
|
2053
3694
|
}
|
|
3695
|
+
// TODO: Support array of selections for multi cursor editing
|
|
2054
3696
|
computedSelection;
|
|
2055
3697
|
setSelection(selection) {
|
|
2056
3698
|
this.computedSelection = selection;
|
|
@@ -2127,12 +3769,12 @@ function toPreviousMatch({ string, re, from }) {
|
|
|
2127
3769
|
if (!re.test(string.slice(0, from)) || from === 0) {
|
|
2128
3770
|
indexOf = -1;
|
|
2129
3771
|
} else {
|
|
2130
|
-
const reversedStringBeforeFrom =
|
|
3772
|
+
const reversedStringBeforeFrom = pipe(
|
|
2131
3773
|
(string2) => string2.slice(0, from),
|
|
2132
3774
|
(sliced) => sliced.split(""),
|
|
2133
3775
|
reverse,
|
|
2134
3776
|
toString
|
|
2135
|
-
), toNextMatchIndex = toNextMatch({ string: reversedStringBeforeFrom, re, from: 0 });
|
|
3777
|
+
)(string), toNextMatchIndex = toNextMatch({ string: reversedStringBeforeFrom, re, from: 0 });
|
|
2136
3778
|
indexOf = toNextMatchIndex === -1 ? -1 : reversedStringBeforeFrom.length - 1 - toNextMatchIndex;
|
|
2137
3779
|
}
|
|
2138
3780
|
return indexOf;
|
|
@@ -2503,11 +4145,12 @@ class Fetchable {
|
|
|
2503
4145
|
computedText;
|
|
2504
4146
|
constructor(resource, options = {}) {
|
|
2505
4147
|
this.setResource(resource);
|
|
2506
|
-
this.
|
|
2507
|
-
this.
|
|
2508
|
-
this.
|
|
2509
|
-
this.
|
|
2510
|
-
this.
|
|
4148
|
+
this.computedKy = ky.create(narrowOptions(options.ky));
|
|
4149
|
+
this.computedArrayBuffer = new Resolveable(async () => "arrayBuffer" in this.response ? await this.response.arrayBuffer() : void 0);
|
|
4150
|
+
this.computedBlob = new Resolveable(async () => "blob" in this.response ? await this.response.blob() : void 0);
|
|
4151
|
+
this.computedFormData = new Resolveable(async () => "formData" in this.response ? await this.response.formData() : void 0);
|
|
4152
|
+
this.computedJson = new Resolveable(async () => "json" in this.response ? await this.response.json() : void 0);
|
|
4153
|
+
this.computedText = new Resolveable(async () => "text" in this.response ? await this.response.text() : void 0);
|
|
2511
4154
|
this.ready();
|
|
2512
4155
|
}
|
|
2513
4156
|
computedStatus;
|
|
@@ -2520,6 +4163,10 @@ class Fetchable {
|
|
|
2520
4163
|
set resource(resource) {
|
|
2521
4164
|
this.setResource(resource);
|
|
2522
4165
|
}
|
|
4166
|
+
computedKy;
|
|
4167
|
+
get ky() {
|
|
4168
|
+
return this.computedKy;
|
|
4169
|
+
}
|
|
2523
4170
|
computedAbortController;
|
|
2524
4171
|
get abortController() {
|
|
2525
4172
|
if (!this.computedAbortController) {
|
|
@@ -2533,6 +4180,10 @@ class Fetchable {
|
|
|
2533
4180
|
get response() {
|
|
2534
4181
|
return this.computedResponse;
|
|
2535
4182
|
}
|
|
4183
|
+
computedRetryCount = 0;
|
|
4184
|
+
get retryCount() {
|
|
4185
|
+
return this.computedRetryCount;
|
|
4186
|
+
}
|
|
2536
4187
|
get error() {
|
|
2537
4188
|
return this.computedError;
|
|
2538
4189
|
}
|
|
@@ -2561,7 +4212,23 @@ class Fetchable {
|
|
|
2561
4212
|
async fetch(options = {}) {
|
|
2562
4213
|
this.fetching();
|
|
2563
4214
|
try {
|
|
2564
|
-
this.computedResponse = await
|
|
4215
|
+
this.computedResponse = await this.ky(
|
|
4216
|
+
this.resource,
|
|
4217
|
+
{
|
|
4218
|
+
...options,
|
|
4219
|
+
signal: this.abortController.signal,
|
|
4220
|
+
hooks: {
|
|
4221
|
+
...options.hooks,
|
|
4222
|
+
beforeRetry: [
|
|
4223
|
+
...options.hooks?.beforeRetry || [],
|
|
4224
|
+
({ retryCount }) => {
|
|
4225
|
+
this.retrying();
|
|
4226
|
+
this.computedRetryCount = retryCount;
|
|
4227
|
+
}
|
|
4228
|
+
]
|
|
4229
|
+
}
|
|
4230
|
+
}
|
|
4231
|
+
);
|
|
2565
4232
|
this.fetched();
|
|
2566
4233
|
} catch (error) {
|
|
2567
4234
|
this.computedError = error;
|
|
@@ -2575,6 +4242,9 @@ class Fetchable {
|
|
|
2575
4242
|
fetching() {
|
|
2576
4243
|
this.computedStatus = "fetching";
|
|
2577
4244
|
}
|
|
4245
|
+
retrying() {
|
|
4246
|
+
this.computedStatus = "retrying";
|
|
4247
|
+
}
|
|
2578
4248
|
fetched() {
|
|
2579
4249
|
this.computedStatus = "fetched";
|
|
2580
4250
|
}
|
|
@@ -2585,23 +4255,27 @@ class Fetchable {
|
|
|
2585
4255
|
this.computedStatus = "errored";
|
|
2586
4256
|
}
|
|
2587
4257
|
async get(options = {}) {
|
|
2588
|
-
await this.fetch({ signal: this.abortController.signal, ...
|
|
4258
|
+
await this.fetch({ signal: this.abortController.signal, ...options, method: "get" });
|
|
2589
4259
|
return this;
|
|
2590
4260
|
}
|
|
2591
4261
|
async patch(options = {}) {
|
|
2592
|
-
await this.fetch({ signal: this.abortController.signal, ...
|
|
4262
|
+
await this.fetch({ signal: this.abortController.signal, ...options, method: "patch" });
|
|
2593
4263
|
return this;
|
|
2594
4264
|
}
|
|
2595
4265
|
async post(options = {}) {
|
|
2596
|
-
await this.fetch({ signal: this.abortController.signal, ...
|
|
4266
|
+
await this.fetch({ signal: this.abortController.signal, ...options, method: "post" });
|
|
2597
4267
|
return this;
|
|
2598
4268
|
}
|
|
2599
4269
|
async put(options = {}) {
|
|
2600
|
-
await this.fetch({ signal: this.abortController.signal, ...
|
|
4270
|
+
await this.fetch({ signal: this.abortController.signal, ...options, method: "put" });
|
|
2601
4271
|
return this;
|
|
2602
4272
|
}
|
|
2603
4273
|
async delete(options = {}) {
|
|
2604
|
-
await this.fetch({ signal: this.abortController.signal, ...
|
|
4274
|
+
await this.fetch({ signal: this.abortController.signal, ...options, method: "delete" });
|
|
4275
|
+
return this;
|
|
4276
|
+
}
|
|
4277
|
+
async head(options = {}) {
|
|
4278
|
+
await this.fetch({ signal: this.abortController.signal, ...options, method: "head" });
|
|
2605
4279
|
return this;
|
|
2606
4280
|
}
|
|
2607
4281
|
abort() {
|
|
@@ -2610,16 +4284,9 @@ class Fetchable {
|
|
|
2610
4284
|
}
|
|
2611
4285
|
}
|
|
2612
4286
|
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
|
-
};
|
|
4287
|
+
if (!options)
|
|
4288
|
+
return {};
|
|
4289
|
+
return predicateFunction(options) ? options({ stop: ky.stop }) : options;
|
|
2623
4290
|
}
|
|
2624
4291
|
|
|
2625
4292
|
class Fullscreenable {
|
|
@@ -2947,13 +4614,12 @@ class Pickable {
|
|
|
2947
4614
|
}
|
|
2948
4615
|
pick(indexOrIndices, options = {}) {
|
|
2949
4616
|
const { replace, allowsDuplicates } = { ...defaultPickOptions, ...options };
|
|
2950
|
-
this.computedPicks =
|
|
4617
|
+
this.computedPicks = pipe(
|
|
2951
4618
|
narrowIndices,
|
|
2952
4619
|
this.toPossiblePicks,
|
|
2953
4620
|
(possiblePicks) => {
|
|
2954
|
-
if (replace === "all")
|
|
4621
|
+
if (replace === "all")
|
|
2955
4622
|
return allowsDuplicates ? possiblePicks : toUnique(possiblePicks);
|
|
2956
|
-
}
|
|
2957
4623
|
const maybeWithoutDuplicates = allowsDuplicates ? possiblePicks : createFilter(
|
|
2958
4624
|
(possiblePick) => typeof find((pick) => pick === possiblePick)(this.picks || []) !== "number"
|
|
2959
4625
|
)(possiblePicks);
|
|
@@ -2970,10 +4636,11 @@ class Pickable {
|
|
|
2970
4636
|
if (maybeWithoutDuplicates.length > this.picks.length) {
|
|
2971
4637
|
return createSlice(maybeWithoutDuplicates.length - this.picks.length)(maybeWithoutDuplicates);
|
|
2972
4638
|
}
|
|
2973
|
-
return
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
4639
|
+
return pipe(
|
|
4640
|
+
slice(maybeWithoutDuplicates.length),
|
|
4641
|
+
(array) => concat(array, maybeWithoutDuplicates),
|
|
4642
|
+
toArray()
|
|
4643
|
+
)(this.picks);
|
|
2977
4644
|
case "lifo":
|
|
2978
4645
|
if (maybeWithoutDuplicates.length === 0) {
|
|
2979
4646
|
return this.picks;
|
|
@@ -2984,13 +4651,14 @@ class Pickable {
|
|
|
2984
4651
|
if (maybeWithoutDuplicates.length > this.picks.length) {
|
|
2985
4652
|
return createSlice(0, maybeWithoutDuplicates.length - this.picks.length + 1)(maybeWithoutDuplicates);
|
|
2986
4653
|
}
|
|
2987
|
-
return
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
4654
|
+
return pipe(
|
|
4655
|
+
slice(0, this.picks.length - maybeWithoutDuplicates.length - 1),
|
|
4656
|
+
(array) => concat(array, maybeWithoutDuplicates),
|
|
4657
|
+
toArray()
|
|
4658
|
+
)(this.picks);
|
|
2991
4659
|
}
|
|
2992
4660
|
}
|
|
2993
|
-
);
|
|
4661
|
+
)(indexOrIndices);
|
|
2994
4662
|
this.computedFirst = Math.min(...this.picks);
|
|
2995
4663
|
this.computedLast = Math.max(...this.picks);
|
|
2996
4664
|
this.computedMultiple = toUnique(this.picks).length > 1;
|
|
@@ -3038,7 +4706,7 @@ class Sanitizeable {
|
|
|
3038
4706
|
computedDompurify;
|
|
3039
4707
|
computedStatus;
|
|
3040
4708
|
ready() {
|
|
3041
|
-
if (
|
|
4709
|
+
if (getDomAvailability() === "available") {
|
|
3042
4710
|
this.computedDompurify = createDOMPurify();
|
|
3043
4711
|
this.computedDompurify.setConfig(this.domPurifyConfig);
|
|
3044
4712
|
}
|
|
@@ -3051,7 +4719,7 @@ class Sanitizeable {
|
|
|
3051
4719
|
this.setHtml(html);
|
|
3052
4720
|
}
|
|
3053
4721
|
get dompurify() {
|
|
3054
|
-
if (!this.computedDompurify &&
|
|
4722
|
+
if (!this.computedDompurify && getDomAvailability() === "available") {
|
|
3055
4723
|
this.computedDompurify = createDOMPurify();
|
|
3056
4724
|
this.computedDompurify.setConfig(this.domPurifyConfig);
|
|
3057
4725
|
}
|
|
@@ -3194,7 +4862,7 @@ class Storeable {
|
|
|
3194
4862
|
computedStatus;
|
|
3195
4863
|
ready() {
|
|
3196
4864
|
this.computedStatus = "ready";
|
|
3197
|
-
if (
|
|
4865
|
+
if (getDomAvailability() === "available") {
|
|
3198
4866
|
if (predicateNull(this.storage.getItem(this.computedStatusKey))) {
|
|
3199
4867
|
this.storeStatus();
|
|
3200
4868
|
}
|
|
@@ -3207,7 +4875,7 @@ class Storeable {
|
|
|
3207
4875
|
this.setKey(key);
|
|
3208
4876
|
}
|
|
3209
4877
|
get status() {
|
|
3210
|
-
if (
|
|
4878
|
+
if (getDomAvailability() === "available") {
|
|
3211
4879
|
const storedStatus = this.storage.getItem(this.computedStatusKey);
|
|
3212
4880
|
if (this.computedStatus !== storedStatus && predicateString(storedStatus)) {
|
|
3213
4881
|
this.computedStatus = storedStatus;
|
|
@@ -3295,4 +4963,4 @@ class Storeable {
|
|
|
3295
4963
|
}
|
|
3296
4964
|
}
|
|
3297
4965
|
|
|
3298
|
-
export { Animateable, Broadcastable, Completeable, Copyable, Delayable, Drawable, Fetchable, Fullscreenable, Grantable, Listenable, Navigateable, Pickable,
|
|
4966
|
+
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, 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 };
|